mirror of https://github.com/NekoX-Dev/NekoX.git
Update to 7.4.0 (2221)
This commit is contained in:
parent
d52de1a40a
commit
77bbe5baec
|
@ -21,7 +21,7 @@ dependencies {
|
|||
implementation 'androidx.exifinterface:exifinterface:1.3.2'
|
||||
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
implementation "androidx.sharetarget:sharetarget:1.0.0"
|
||||
implementation "androidx.sharetarget:sharetarget:1.1.0"
|
||||
|
||||
compileOnly 'org.checkerframework:checker-qual:2.5.2'
|
||||
compileOnly 'org.checkerframework:checker-compat-qual:2.5.0'
|
||||
|
@ -290,7 +290,7 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
defaultConfig.versionCode = 2206
|
||||
defaultConfig.versionCode = 2221
|
||||
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.all { output ->
|
||||
|
@ -309,7 +309,7 @@ android {
|
|||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 29
|
||||
versionName "7.3.1"
|
||||
versionName "7.4.0"
|
||||
|
||||
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']
|
||||
|
||||
|
|
|
@ -426,6 +426,21 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNati
|
|||
env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onSignalBarsUpdated", "(I)V"), count);
|
||||
});
|
||||
},
|
||||
.audioLevelUpdated = [platformContext](float level) {
|
||||
tgvoip::jni::DoWithJNI([platformContext, level](JNIEnv *env) {
|
||||
jintArray intArray = nullptr;
|
||||
jfloatArray floatArray = env->NewFloatArray(1);
|
||||
jbooleanArray boolArray = nullptr;
|
||||
|
||||
jfloat floatFill[1];
|
||||
floatFill[0] = level;
|
||||
env->SetFloatArrayRegion(floatArray, 0, 1, floatFill);
|
||||
|
||||
jobject globalRef = ((AndroidContext *) platformContext.get())->getJavaInstance();
|
||||
env->CallVoidMethod(globalRef, env->GetMethodID(NativeInstanceClass, "onAudioLevelsUpdated", "([I[F[Z)V"), intArray, floatArray, boolArray);
|
||||
env->DeleteLocalRef(floatArray);
|
||||
});
|
||||
},
|
||||
.remoteMediaStateUpdated = [platformContext](AudioState audioState, VideoState videoState) {
|
||||
jobject globalRef = ((AndroidContext *) platformContext.get())->getJavaInstance();
|
||||
tgvoip::jni::DoWithJNI([globalRef, audioState, videoState](JNIEnv *env) {
|
||||
|
@ -521,6 +536,13 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setMuteMi
|
|||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setVolume(JNIEnv *env, jobject obj, jint ssrc, jdouble volume) {
|
||||
InstanceHolder *instance = getInstanceHolder(env, obj);
|
||||
if (instance->groupNativeInstance != nullptr) {
|
||||
instance->groupNativeInstance->setVolume(ssrc, volume);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setAudioOutputGainControlEnabled(JNIEnv *env, jobject obj, jboolean enabled) {
|
||||
InstanceHolder *instance = getInstanceHolder(env, obj);
|
||||
if (instance->nativeInstance == nullptr) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "modules/rtp_rtcp/source/rtp_utility.h"
|
||||
#include "api/call/audio_sink.h"
|
||||
#include "modules/audio_processing/audio_buffer.h"
|
||||
#include "modules/audio_device/include/audio_device_factory.h"
|
||||
|
||||
namespace tgcalls {
|
||||
namespace {
|
||||
|
@ -45,6 +46,31 @@ VideoCaptureInterfaceObject *GetVideoCaptureAssumingSameThread(VideoCaptureInter
|
|||
: nullptr;
|
||||
}
|
||||
|
||||
class AudioCaptureAnalyzer : public webrtc::CustomAudioAnalyzer {
|
||||
private:
|
||||
void Initialize(int sample_rate_hz, int num_channels) override {
|
||||
|
||||
}
|
||||
// Analyzes the given capture or render signal.
|
||||
void Analyze(const webrtc::AudioBuffer* audio) override {
|
||||
_analyze(audio);
|
||||
}
|
||||
// Returns a string representation of the module state.
|
||||
std::string ToString() const override {
|
||||
return "analyzing";
|
||||
}
|
||||
|
||||
std::function<void(const webrtc::AudioBuffer*)> _analyze;
|
||||
|
||||
public:
|
||||
AudioCaptureAnalyzer(std::function<void(const webrtc::AudioBuffer*)> analyze) :
|
||||
_analyze(analyze) {
|
||||
}
|
||||
|
||||
virtual ~AudioCaptureAnalyzer() = default;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
class VideoSinkInterfaceProxyImpl : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
|
||||
|
@ -87,7 +113,7 @@ private:
|
|||
class AudioTrackSinkInterfaceImpl: public webrtc::AudioSinkInterface {
|
||||
private:
|
||||
std::function<void(float)> _update;
|
||||
|
||||
|
||||
int _peakCount = 0;
|
||||
uint16_t _peak = 0;
|
||||
|
||||
|
@ -103,7 +129,7 @@ public:
|
|||
if (audio.channels == 1) {
|
||||
int16_t *samples = (int16_t *)audio.data;
|
||||
int numberOfSamplesInFrame = (int)audio.samples_per_channel;
|
||||
|
||||
|
||||
for (int i = 0; i < numberOfSamplesInFrame; i++) {
|
||||
int16_t sample = samples[i];
|
||||
if (sample < 0) {
|
||||
|
@ -114,7 +140,7 @@ public:
|
|||
}
|
||||
_peakCount += 1;
|
||||
}
|
||||
|
||||
|
||||
if (_peakCount >= 1200) {
|
||||
float level = ((float)(_peak)) / 4000.0f;
|
||||
_peak = 0;
|
||||
|
@ -206,7 +232,49 @@ _platformContext(platformContext) {
|
|||
preferredCodecs,
|
||||
_platformContext);
|
||||
|
||||
mediaDeps.audio_processing = webrtc::AudioProcessingBuilder().Create();
|
||||
// [this] should outlive the analyzer
|
||||
auto analyzer = new AudioCaptureAnalyzer([this](const webrtc::AudioBuffer* buffer) {
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
if (buffer->num_channels() != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
float peak = 0;
|
||||
int peakCount = 0;
|
||||
const float *samples = buffer->channels_const()[0];
|
||||
for (int i = 0; i < buffer->num_frames(); i++) {
|
||||
float sample = samples[i];
|
||||
if (sample < 0) {
|
||||
sample = -sample;
|
||||
}
|
||||
if (peak < sample) {
|
||||
peak = sample;
|
||||
}
|
||||
peakCount += 1;
|
||||
}
|
||||
|
||||
this->_thread->PostTask(RTC_FROM_HERE, [this, peak, peakCount](){
|
||||
auto strong = this;
|
||||
|
||||
strong->_myAudioLevelPeakCount += peakCount;
|
||||
if (strong->_myAudioLevelPeak < peak) {
|
||||
strong->_myAudioLevelPeak = peak;
|
||||
}
|
||||
if (strong->_myAudioLevelPeakCount >= 1200) {
|
||||
float level = strong->_myAudioLevelPeak / 4000.0f;
|
||||
strong->_myAudioLevelPeak = 0;
|
||||
strong->_myAudioLevelPeakCount = 0;
|
||||
strong->_currentMyAudioLevel = level;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
webrtc::AudioProcessingBuilder builder;
|
||||
builder.SetCaptureAnalyzer(std::unique_ptr<AudioCaptureAnalyzer>(analyzer));
|
||||
|
||||
mediaDeps.audio_processing = builder.Create();
|
||||
|
||||
/*_audioDeviceModule = createAudioDeviceModule();
|
||||
if (!_audioDeviceModule) {
|
||||
|
@ -298,6 +366,13 @@ rtc::scoped_refptr<webrtc::AudioDeviceModule> MediaManager::createAudioDeviceMod
|
|||
_taskQueueFactory.get());
|
||||
return (result && (result->Init() == 0)) ? result : nullptr;
|
||||
};
|
||||
#ifdef WEBRTC_WIN
|
||||
if (auto result = webrtc::CreateWindowsCoreAudioAudioDeviceModule(_taskQueueFactory.get())) {
|
||||
if (result->Init() == 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif // WEBRTC_WIN
|
||||
if (auto result = check(webrtc::AudioDeviceModule::kPlatformDefaultAudio)) {
|
||||
return result;
|
||||
#ifdef WEBRTC_LINUX
|
||||
|
@ -310,7 +385,7 @@ rtc::scoped_refptr<webrtc::AudioDeviceModule> MediaManager::createAudioDeviceMod
|
|||
|
||||
void MediaManager::start() {
|
||||
const auto weak = std::weak_ptr<MediaManager>(shared_from_this());
|
||||
|
||||
|
||||
// Here we hope that thread outlives the sink
|
||||
rtc::Thread *thread = _thread;
|
||||
std::unique_ptr<AudioTrackSinkInterfaceImpl> incomingSink(new AudioTrackSinkInterfaceImpl([weak, thread](float level) {
|
||||
|
@ -320,24 +395,16 @@ void MediaManager::start() {
|
|||
}
|
||||
});
|
||||
}));
|
||||
std::unique_ptr<AudioTrackSinkInterfaceImpl> outgoingSink(new AudioTrackSinkInterfaceImpl([weak, thread](float level) {
|
||||
thread->PostTask(RTC_FROM_HERE, [weak, level] {
|
||||
if (const auto strong = weak.lock()) {
|
||||
strong->_currentMyAudioLevel = level;
|
||||
}
|
||||
});
|
||||
}));
|
||||
_audioChannel->SetRawAudioSink(_ssrcAudio.incoming, std::move(incomingSink));
|
||||
_audioChannel->SetRawAudioSink(_ssrcAudio.outgoing, std::move(outgoingSink));
|
||||
|
||||
_sendSignalingMessage({ _myVideoFormats });
|
||||
|
||||
_sendSignalingMessage({ _myVideoFormats });
|
||||
|
||||
if (_videoCapture != nullptr) {
|
||||
setSendVideo(_videoCapture);
|
||||
}
|
||||
|
||||
beginStatsTimer(3000);
|
||||
if (_audioLevelUpdated != nullptr) {
|
||||
if (_audioLevelUpdated != nullptr) {
|
||||
beginLevelsTimer(50);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,6 +164,8 @@ private:
|
|||
|
||||
float _currentAudioLevel = 0.0f;
|
||||
float _currentMyAudioLevel = 0.0f;
|
||||
int _myAudioLevelPeakCount = 0;
|
||||
int _myAudioLevelPeak = 0;
|
||||
|
||||
std::unique_ptr<MediaManager::NetworkInterfaceImpl> _audioNetworkInterface;
|
||||
std::unique_ptr<MediaManager::NetworkInterfaceImpl> _videoNetworkInterface;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "system_wrappers/include/field_trial.h"
|
||||
#include "api/stats/rtcstats_objects.h"
|
||||
#include "modules/audio_processing/audio_buffer.h"
|
||||
#include "modules/audio_device/include/audio_device_factory.h"
|
||||
#include "common_audio/include/audio_util.h"
|
||||
#include "common_audio/vad/include/webrtc_vad.h"
|
||||
#include "modules/audio_processing/agc2/vad_with_level.h"
|
||||
|
@ -1091,6 +1092,14 @@ public:
|
|||
dependencies.task_queue_factory.get());
|
||||
return (result && (result->Init() == 0)) ? result : nullptr;
|
||||
};
|
||||
#ifdef WEBRTC_WIN
|
||||
if (auto result = webrtc::CreateWindowsCoreAudioAudioDeviceModule(dependencies.task_queue_factory.get())) {
|
||||
if (result->Init() == 0) {
|
||||
_adm_use_withAudioDeviceModule = new rtc::RefCountedObject<WrappedAudioDeviceModule>(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // WEBRTC_WIN
|
||||
if (auto result = check(webrtc::AudioDeviceModule::kPlatformDefaultAudio)) {
|
||||
_adm_use_withAudioDeviceModule = new rtc::RefCountedObject<WrappedAudioDeviceModule>(result);
|
||||
#ifdef WEBRTC_LINUX
|
||||
|
@ -1326,7 +1335,7 @@ public:
|
|||
adm->EnableBuiltInAEC(false);
|
||||
#endif // WEBRTC_WIN
|
||||
|
||||
if (adm->InitPlayout()) {
|
||||
if (adm->InitPlayout() == 0) {
|
||||
adm->StartPlayout();
|
||||
} else {
|
||||
getMediaThread()->PostDelayedTask(RTC_FROM_HERE, [weak](){
|
||||
|
@ -1335,7 +1344,7 @@ public:
|
|||
return;
|
||||
}
|
||||
strong->withAudioDeviceModule([](webrtc::AudioDeviceModule *adm) {
|
||||
if (adm->InitPlayout()) {
|
||||
if (adm->InitPlayout() == 0) {
|
||||
adm->StartPlayout();
|
||||
}
|
||||
});
|
||||
|
@ -1443,6 +1452,27 @@ public:
|
|||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void setVolume(uint32_t ssrc, double volume) {
|
||||
auto current = _audioTrackVolumes.find(ssrc);
|
||||
bool updated = false;
|
||||
if (current != _audioTrackVolumes.end()) {
|
||||
if (abs(current->second - volume) > 0.001) {
|
||||
updated = true;
|
||||
}
|
||||
} else {
|
||||
if (volume < 1.0 - 0.001) {
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
_audioTrackVolumes[ssrc] = volume;
|
||||
auto track = _audioTracks.find(ssrc);
|
||||
if (track != _audioTracks.end()) {
|
||||
track->second->GetSource()->SetVolume(volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateIsConnected(bool isConnected) {
|
||||
_isConnected = isConnected;
|
||||
|
@ -1792,7 +1822,14 @@ public:
|
|||
uint32_t ssrc = 0;
|
||||
iss >> ssrc;
|
||||
|
||||
auto remoteAudioTrack = static_cast<webrtc::AudioTrackInterface *>(transceiver->receiver()->track().get());
|
||||
rtc::scoped_refptr<webrtc::AudioTrackInterface> remoteAudioTrack(static_cast<webrtc::AudioTrackInterface *>(transceiver->receiver()->track().get()));
|
||||
if (_audioTracks.find(ssrc) == _audioTracks.end()) {
|
||||
_audioTracks.insert(std::make_pair(ssrc, remoteAudioTrack));
|
||||
}
|
||||
auto currentVolume = _audioTrackVolumes.find(ssrc);
|
||||
if (currentVolume != _audioTrackVolumes.end()) {
|
||||
remoteAudioTrack->GetSource()->SetVolume(currentVolume->second);
|
||||
}
|
||||
if (_audioTrackSinks.find(ssrc) == _audioTrackSinks.end()) {
|
||||
const auto weak = std::weak_ptr<GroupInstanceManager>(shared_from_this());
|
||||
std::shared_ptr<AudioTrackSinkInterfaceImpl> sink(new AudioTrackSinkInterfaceImpl([weak, ssrc](float level, bool hasSpeech) {
|
||||
|
@ -1821,6 +1858,7 @@ public:
|
|||
}));
|
||||
_audioTrackSinks[ssrc] = sink;
|
||||
remoteAudioTrack->AddSink(sink.get());
|
||||
//remoteAudioTrack->GetSource()->SetVolume(0.01);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2048,8 +2086,10 @@ private:
|
|||
rtc::Thread *_adm_thread = nullptr;
|
||||
rtc::scoped_refptr<webrtc::AudioDeviceModule> _adm_use_withAudioDeviceModule;
|
||||
|
||||
std::map<uint32_t, rtc::scoped_refptr<webrtc::AudioTrackInterface>> _audioTracks;
|
||||
std::map<uint32_t, std::shared_ptr<AudioTrackSinkInterfaceImpl>> _audioTrackSinks;
|
||||
std::map<uint32_t, GroupLevelValue> _audioLevels;
|
||||
std::map<uint32_t, double> _audioTrackVolumes;
|
||||
|
||||
std::shared_ptr<PlatformContext> _platformContext;
|
||||
};
|
||||
|
@ -2122,4 +2162,10 @@ void GroupInstanceImpl::setAudioOutputDevice(std::string id) {
|
|||
});
|
||||
}
|
||||
|
||||
void GroupInstanceImpl::setVolume(uint32_t ssrc, double volume) {
|
||||
_manager->perform(RTC_FROM_HERE, [ssrc, volume](GroupInstanceManager *manager) {
|
||||
manager->setVolume(ssrc, volume);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace tgcalls
|
||||
|
|
|
@ -102,6 +102,8 @@ public:
|
|||
void setIsMuted(bool isMuted);
|
||||
void setAudioOutputDevice(std::string id);
|
||||
void setAudioInputDevice(std::string id);
|
||||
|
||||
void setVolume(uint32_t ssrc, double volume);
|
||||
|
||||
struct AudioDevice {
|
||||
enum class Type {Input, Output};
|
||||
|
|
|
@ -240,9 +240,9 @@ void InstanceImplLegacy::setOutputVolume(float level) {
|
|||
}
|
||||
|
||||
void InstanceImplLegacy::setAudioOutputDuckingEnabled(bool enabled) {
|
||||
#if defined(__APPLE__) && defined(TARGET_OS_OSX)
|
||||
#if defined(__APPLE__) && TARGET_OS_OSX
|
||||
controller_->SetAudioOutputDuckingEnabled(enabled);
|
||||
#endif
|
||||
#endif // TARGET_OS_OSX
|
||||
}
|
||||
|
||||
void InstanceImplLegacy::setIsLowBatteryLevel(bool isLowBatteryLevel) {
|
||||
|
|
|
@ -199,6 +199,24 @@
|
|||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- <activity-->
|
||||
<!-- android:name="org.telegram.ui.ShortcutWidgetConfigActivity"-->
|
||||
<!-- android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"-->
|
||||
<!-- android:hardwareAccelerated="@bool/useHardwareAcceleration"-->
|
||||
<!-- android:windowSoftInputMode="adjustPan">-->
|
||||
<!-- <intent-filter android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round">-->
|
||||
<!-- <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </activity>-->
|
||||
<!-- <activity-->
|
||||
<!-- android:name="org.telegram.ui.FeedWidgetConfigActivity"-->
|
||||
<!-- android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"-->
|
||||
<!-- android:hardwareAccelerated="@bool/useHardwareAcceleration"-->
|
||||
<!-- android:windowSoftInputMode="adjustPan">-->
|
||||
<!-- <intent-filter android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round">-->
|
||||
<!-- <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </activity>-->
|
||||
<activity
|
||||
android:name="org.telegram.ui.IntroActivity"
|
||||
android:launchMode="singleTask"
|
||||
|
@ -302,6 +320,7 @@
|
|||
<service android:name=".NotificationsService" android:enabled="true"/>
|
||||
<service android:name=".NotificationRepeat" android:exported="false"/>
|
||||
<service android:name=".VideoEncodingService" android:enabled="true"/>
|
||||
<service android:name=".ImportingService" android:enabled="true"/>
|
||||
<service android:name=".LocationSharingService"
|
||||
android:foregroundServiceType="location"
|
||||
android:enabled="true"/>
|
||||
|
@ -396,6 +415,30 @@
|
|||
android:name=".voip.CallNotificationSoundProvider"
|
||||
android:exported="true"/>
|
||||
|
||||
<!-- <receiver android:name=".ShortcutWidgetProvider">-->
|
||||
<!-- <meta-data android:name="android.appwidget.provider"-->
|
||||
<!-- android:resource="@xml/shortcut_widget_info" />-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<!-- <service android:name=".ShortcutWidgetService"-->
|
||||
<!-- android:permission="android.permission.BIND_REMOTEVIEWS"-->
|
||||
<!-- android:exported="false" />-->
|
||||
|
||||
<!-- <receiver android:name=".FeedWidgetProvider">-->
|
||||
<!-- <meta-data android:name="android.appwidget.provider"-->
|
||||
<!-- android:resource="@xml/feed_widget_info" />-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<!-- <service android:name=".FeedWidgetService"-->
|
||||
<!-- android:permission="android.permission.BIND_REMOTEVIEWS"-->
|
||||
<!-- android:exported="false" />-->
|
||||
|
||||
<uses-library android:name="com.sec.android.app.multiwindow" android:required="false" />
|
||||
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
||||
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632dp" />
|
||||
|
|
|
@ -1397,9 +1397,6 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
|
|||
}
|
||||
final int scrolled = absDelta > consumed ? layoutDirection * consumed : delta;
|
||||
mOrientationHelper.offsetChildren(-scrolled);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "scroll req: " + delta + " scrolled: " + scrolled);
|
||||
}
|
||||
mLayoutState.mLastScrollDelta = scrolled;
|
||||
return scrolled;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ import com.google.zxing.qrcode.encoder.Encoder;
|
|||
import com.google.zxing.qrcode.encoder.QRCode;
|
||||
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.SvgHelper;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.RLottieDrawable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
@ -115,7 +118,7 @@ public final class QRCodeWriter {
|
|||
imageBloks++;
|
||||
}
|
||||
imageBlockX = (inputWidth - imageBloks) / 2;
|
||||
int imageSize = imageBloks * multiple;
|
||||
int imageSize = imageBloks * multiple - 24;
|
||||
int imageX = (size - imageSize) / 2;
|
||||
|
||||
for (int a = 0; a < 3; a++) {
|
||||
|
@ -206,9 +209,14 @@ public final class QRCodeWriter {
|
|||
}
|
||||
}
|
||||
|
||||
Drawable drawable = context.getResources().getDrawable(R.drawable.gem_l).mutate();
|
||||
drawable.setBounds(imageX, imageX, imageX + imageSize, imageX + imageSize);
|
||||
drawable.draw(canvas);
|
||||
String svg = RLottieDrawable.readRes(null, R.raw.qr_logo);
|
||||
Bitmap icon = SvgHelper.getBitmap(svg, imageSize, imageSize, false);
|
||||
|
||||
// Drawable drawable = context.getResources().getDrawable(R.drawable.ic_launcher_dr).mutate();
|
||||
// drawable.setBounds(imageX, imageX, imageX + imageSize, imageX + imageSize);
|
||||
// drawable.draw(canvas);
|
||||
canvas.drawBitmap(icon, imageX, imageX, null);
|
||||
icon.recycle();
|
||||
|
||||
canvas.setBitmap(null);
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ import android.provider.Settings;
|
|||
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import android.telephony.TelephonyManager;
|
||||
|
@ -65,6 +66,10 @@ import android.text.TextUtils;
|
|||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.transition.ChangeBounds;
|
||||
import android.transition.TransitionSet;
|
||||
import android.transition.TransitionValues;
|
||||
import android.transition.Visibility;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.StateSet;
|
||||
import android.util.TypedValue;
|
||||
|
@ -107,12 +112,14 @@ import org.telegram.tgnet.ConnectionsManager;
|
|||
import org.telegram.tgnet.TLObject;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.ActionBarLayout;
|
||||
import org.telegram.ui.ActionBar.ActionBarMenuItem;
|
||||
import org.telegram.ui.ActionBar.AlertDialog;
|
||||
import org.telegram.ui.ActionBar.BaseFragment;
|
||||
import org.telegram.ui.ActionBar.BottomSheet;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Cells.TextDetailSettingsCell;
|
||||
import org.telegram.ui.Components.BackgroundGradientDrawable;
|
||||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||
import org.telegram.ui.Components.ForegroundColorSpanThemable;
|
||||
import org.telegram.ui.Components.ForegroundDetector;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
|
@ -3624,4 +3631,25 @@ public class AndroidUtilities {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void updateVisibleRows(RecyclerListView listView) {
|
||||
if (listView == null) {
|
||||
return;
|
||||
}
|
||||
RecyclerView.Adapter adapter = listView.getAdapter();
|
||||
if (adapter == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||
View child = listView.getChildAt(i);
|
||||
int p = listView.getChildAdapterPosition(child);
|
||||
if (p >= 0) {
|
||||
RecyclerView.ViewHolder holder = listView.getChildViewHolder(child);
|
||||
if (holder == null || holder.shouldIgnore()) {
|
||||
continue;
|
||||
}
|
||||
adapter.onBindViewHolder(holder, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ public class BuildVars {
|
|||
public static boolean LOGS_ENABLED = false;
|
||||
public static boolean USE_CLOUD_STRINGS = true;
|
||||
public static boolean CHECK_UPDATES = true;
|
||||
public static int BUILD_VERSION = 2206;
|
||||
public static String BUILD_VERSION_STRING = "7.3.0";
|
||||
public static int BUILD_VERSION = 2221;
|
||||
public static String BUILD_VERSION_STRING = "7.4.0";
|
||||
public static int APP_ID = 4;
|
||||
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
|
||||
public static String APPCENTER_HASH = "a5b5c4f5-51da-dedc-9918-d9766a22ca7c";
|
||||
|
|
|
@ -143,17 +143,27 @@ public class ChatObject {
|
|||
call.version = groupParticipants.version;
|
||||
call.participants_count = groupParticipants.count;
|
||||
}
|
||||
long time = SystemClock.elapsedRealtime();
|
||||
currentAccount.getNotificationCenter().postNotificationName(NotificationCenter.applyGroupCallVisibleParticipants, time);
|
||||
for (int a = 0, N = groupParticipants.participants.size(); a < N; a++) {
|
||||
TLRPC.TL_groupCallParticipant participant = groupParticipants.participants.get(a);
|
||||
TLRPC.TL_groupCallParticipant oldParticipant = participants.get(participant.user_id);
|
||||
if (oldParticipant != null) {
|
||||
sortedParticipants.remove(oldParticipant);
|
||||
participantsBySources.remove(oldParticipant.source);
|
||||
participant.active_date = Math.max(participant.active_date, oldParticipant.active_date);
|
||||
participant.lastTypingDate = Math.max(participant.active_date, oldParticipant.active_date);
|
||||
if (time != participant.lastVisibleDate) {
|
||||
participant.active_date = participant.lastTypingDate;
|
||||
}
|
||||
} else if (old != null) {
|
||||
oldParticipant = old.get(participant.user_id);
|
||||
if (oldParticipant != null) {
|
||||
participant.active_date = Math.max(participant.active_date, oldParticipant.active_date);
|
||||
participant.lastTypingDate = Math.max(participant.active_date, oldParticipant.active_date);
|
||||
if (time != participant.lastVisibleDate) {
|
||||
participant.active_date = participant.lastTypingDate;
|
||||
} else {
|
||||
participant.active_date = oldParticipant.active_date;
|
||||
}
|
||||
}
|
||||
}
|
||||
participants.put(participant.user_id, participant);
|
||||
|
@ -180,12 +190,19 @@ public class ChatObject {
|
|||
public void processTypingsUpdate(AccountInstance accountInstance, ArrayList<Integer> uids, int date) {
|
||||
boolean updated = false;
|
||||
ArrayList<Integer> participantsToLoad = null;
|
||||
long time = SystemClock.elapsedRealtime();
|
||||
currentAccount.getNotificationCenter().postNotificationName(NotificationCenter.applyGroupCallVisibleParticipants, time);
|
||||
for (int a = 0, N = uids.size(); a < N; a++) {
|
||||
Integer id = uids.get(a);
|
||||
TLRPC.TL_groupCallParticipant participant = participants.get(id);
|
||||
if (participant != null) {
|
||||
participant.active_date = date;
|
||||
updated = true;
|
||||
if (date - participant.lastTypingDate > 10) {
|
||||
if (participant.lastVisibleDate != date) {
|
||||
participant.active_date = date;
|
||||
}
|
||||
participant.lastTypingDate = date;
|
||||
updated = true;
|
||||
}
|
||||
} else {
|
||||
if (participantsToLoad == null) {
|
||||
participantsToLoad = new ArrayList<>();
|
||||
|
@ -252,6 +269,8 @@ public class ChatObject {
|
|||
boolean updated = false;
|
||||
int currentTime = currentAccount.getConnectionsManager().getCurrentTime();
|
||||
ArrayList<Integer> participantsToLoad = null;
|
||||
long time = SystemClock.elapsedRealtime();
|
||||
currentAccount.getNotificationCenter().postNotificationName(NotificationCenter.applyGroupCallVisibleParticipants, time);
|
||||
for (int a = 0; a < ssrc.length; a++) {
|
||||
TLRPC.TL_groupCallParticipant participant;
|
||||
if (ssrc[a] == 0) {
|
||||
|
@ -262,8 +281,11 @@ public class ChatObject {
|
|||
if (participant != null) {
|
||||
participant.hasVoice = voice[a];
|
||||
if (levels[a] > 0.1f) {
|
||||
if (voice[a] && participant.active_date + 1 < currentTime) {
|
||||
participant.active_date = currentTime;
|
||||
if (voice[a] && participant.lastTypingDate + 1 < currentTime) {
|
||||
if (time != participant.lastVisibleDate) {
|
||||
participant.active_date = currentTime;
|
||||
}
|
||||
participant.lastTypingDate = currentTime;
|
||||
updated = true;
|
||||
}
|
||||
participant.lastSpeakTime = SystemClock.uptimeMillis();
|
||||
|
@ -388,6 +410,8 @@ public class ChatObject {
|
|||
boolean updated = false;
|
||||
boolean selfUpdated = false;
|
||||
int selfId = currentAccount.getUserConfig().getClientUserId();
|
||||
long time = SystemClock.elapsedRealtime();
|
||||
currentAccount.getNotificationCenter().postNotificationName(NotificationCenter.applyGroupCallVisibleParticipants, time);
|
||||
for (int a = 0, N = update.participants.size(); a < N; a++) {
|
||||
TLRPC.TL_groupCallParticipant participant = update.participants.get(a);
|
||||
TLRPC.TL_groupCallParticipant oldParticipant = participants.get(participant.user_id);
|
||||
|
@ -414,9 +438,14 @@ public class ChatObject {
|
|||
if (oldParticipant != null) {
|
||||
oldParticipant.flags = participant.flags;
|
||||
oldParticipant.muted = participant.muted;
|
||||
oldParticipant.muted_by_you = participant.muted_by_you;
|
||||
oldParticipant.volume = participant.volume;
|
||||
oldParticipant.can_self_unmute = participant.can_self_unmute;
|
||||
oldParticipant.date = participant.date;
|
||||
oldParticipant.active_date = Math.max(oldParticipant.active_date, participant.active_date);
|
||||
oldParticipant.lastTypingDate = Math.max(oldParticipant.active_date, participant.active_date);
|
||||
if (time != oldParticipant.lastVisibleDate) {
|
||||
oldParticipant.active_date = oldParticipant.lastTypingDate;
|
||||
}
|
||||
if (oldParticipant.source != participant.source) {
|
||||
participantsBySources.remove(oldParticipant.source);
|
||||
oldParticipant.source = participant.source;
|
||||
|
@ -484,6 +513,13 @@ public class ChatObject {
|
|||
checkOnlineParticipants();
|
||||
}
|
||||
|
||||
public void saveActiveDates() {
|
||||
for (int a = 0, N = sortedParticipants.size(); a < N; a++) {
|
||||
TLRPC.TL_groupCallParticipant p = sortedParticipants.get(a);
|
||||
p.lastActiveDate = p.active_date;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOnlineParticipants() {
|
||||
if (typingUpdateRunnableScheduled) {
|
||||
AndroidUtilities.cancelRunOnUIThread(typingUpdateRunnable);
|
||||
|
@ -510,6 +546,10 @@ public class ChatObject {
|
|||
}
|
||||
}
|
||||
|
||||
public static int getParticipantVolume(TLRPC.TL_groupCallParticipant participant) {
|
||||
return ((participant.flags & 128) != 0 ? participant.volume : 10000);
|
||||
}
|
||||
|
||||
private static boolean isBannableAction(int action) {
|
||||
switch (action) {
|
||||
case ACTION_PIN:
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package org.telegram.messenger;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import org.telegram.ui.FeedWidgetConfigActivity;
|
||||
import org.telegram.ui.LaunchActivity;
|
||||
|
||||
public class FeedWidgetProvider extends AppWidgetProvider {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds);
|
||||
for (int i = 0; i < appWidgetIds.length; i++) {
|
||||
int appWidgetId = appWidgetIds[i];
|
||||
updateWidget(context, appWidgetManager, appWidgetId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(Context context, int[] appWidgetIds) {
|
||||
super.onDeleted(context, appWidgetIds);
|
||||
for (int a = 0; a < appWidgetIds.length; a++) {
|
||||
SharedPreferences preferences = context.getSharedPreferences("feed_widget", Activity.MODE_PRIVATE);
|
||||
preferences.edit().remove("account" + appWidgetIds[a]).remove("dialogId" + appWidgetIds[a]).commit();
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
|
||||
Intent intent2 = new Intent(context, FeedWidgetService.class);
|
||||
intent2.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
intent2.setData(Uri.parse(intent2.toUri(Intent.URI_INTENT_SCHEME)));
|
||||
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.feed_widget_layout);
|
||||
rv.setRemoteAdapter(appWidgetId, R.id.list_view, intent2);
|
||||
rv.setEmptyView(R.id.list_view, R.id.empty_view);
|
||||
|
||||
Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class);
|
||||
intent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
rv.setPendingIntentTemplate(R.id.list_view, contentIntent);
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, rv);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
package org.telegram.messenger;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.RemoteViewsService;
|
||||
|
||||
import org.telegram.tgnet.ConnectionsManager;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
public class FeedWidgetService extends RemoteViewsService {
|
||||
@Override
|
||||
public RemoteViewsFactory onGetViewFactory(Intent intent) {
|
||||
return new FeedRemoteViewsFactory(getApplicationContext(), intent);
|
||||
}
|
||||
}
|
||||
|
||||
class FeedRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory, NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
private ArrayList<MessageObject> messages = new ArrayList<>();
|
||||
private Context mContext;
|
||||
private int appWidgetId;
|
||||
private long dialogId;
|
||||
private int classGuid;
|
||||
private AccountInstance accountInstance;
|
||||
private CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
|
||||
public FeedRemoteViewsFactory(Context context, Intent intent) {
|
||||
mContext = context;
|
||||
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||
SharedPreferences preferences = context.getSharedPreferences("feed_widget", Activity.MODE_PRIVATE);
|
||||
int accountId = preferences.getInt("account" + appWidgetId, -1);
|
||||
if (accountId >= 0) {
|
||||
dialogId = preferences.getLong("dialogId" + appWidgetId, 0);
|
||||
accountInstance = AccountInstance.getInstance(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
public void onCreate() {
|
||||
ApplicationLoader.postInitApplication();
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return messages.size();
|
||||
}
|
||||
|
||||
protected void grantUriAccessToWidget(Context context, Uri uri) {
|
||||
Intent intent= new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_HOME);
|
||||
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
for (ResolveInfo resolveInfo : resInfoList) {
|
||||
String packageName = resolveInfo.activityInfo.packageName;
|
||||
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteViews getViewAt(int position) {
|
||||
MessageObject messageObject = messages.get(position);
|
||||
String name;
|
||||
|
||||
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.feed_widget_item);
|
||||
if (messageObject.type == 0) {
|
||||
rv.setTextViewText(R.id.feed_widget_item_text, messageObject.messageText);
|
||||
rv.setViewVisibility(R.id.feed_widget_item_text, View.VISIBLE);
|
||||
} else {
|
||||
if (TextUtils.isEmpty(messageObject.caption)) {
|
||||
rv.setViewVisibility(R.id.feed_widget_item_text, View.GONE);
|
||||
} else {
|
||||
rv.setTextViewText(R.id.feed_widget_item_text, messageObject.caption);
|
||||
rv.setViewVisibility(R.id.feed_widget_item_text, View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (messageObject.photoThumbs == null || messageObject.photoThumbs.isEmpty()) {
|
||||
rv.setViewVisibility(R.id.feed_widget_item_image, View.GONE);
|
||||
} else {
|
||||
TLRPC.PhotoSize size = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize());
|
||||
File f = FileLoader.getPathToAttach(size);
|
||||
if (f.exists()) {
|
||||
rv.setViewVisibility(R.id.feed_widget_item_image, View.VISIBLE);
|
||||
Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", f);
|
||||
grantUriAccessToWidget(mContext, uri);
|
||||
rv.setImageViewUri(R.id.feed_widget_item_image, uri);
|
||||
} else {
|
||||
rv.setViewVisibility(R.id.feed_widget_item_image, View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt("chatId", (int) -messageObject.getDialogId());
|
||||
extras.putInt("message_id", messageObject.getId());
|
||||
extras.putInt("currentAccount", accountInstance.getCurrentAccount());
|
||||
|
||||
Intent fillInIntent = new Intent();
|
||||
fillInIntent.putExtras(extras);
|
||||
rv.setOnClickFillInIntent(R.id.shortcut_widget_item, fillInIntent);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
public RemoteViews getLoadingView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getViewTypeCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onDataSetChanged() {
|
||||
if (accountInstance == null || !accountInstance.getUserConfig().isClientActivated()) {
|
||||
messages.clear();
|
||||
return;
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
accountInstance.getNotificationCenter().addObserver(FeedRemoteViewsFactory.this, NotificationCenter.messagesDidLoad);
|
||||
if (classGuid == 0) {
|
||||
classGuid = ConnectionsManager.generateClassGuid();
|
||||
}
|
||||
accountInstance.getMessagesController().loadMessages(dialogId, 0, false, 20, 0, 0, true, 0, classGuid, 0, 0, true, 0, 0, 0, 1);
|
||||
});
|
||||
try {
|
||||
countDownLatch.await();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void didReceivedNotification(int id, int account, Object... args) {
|
||||
if (id == NotificationCenter.messagesDidLoad) {
|
||||
int guid = (Integer) args[10];
|
||||
if (guid == classGuid) {
|
||||
messages.clear();
|
||||
ArrayList<MessageObject> messArr = (ArrayList<MessageObject>) args[2];
|
||||
messages.addAll(messArr);
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -97,6 +97,8 @@ public class FileLoadOperation {
|
|||
|
||||
private boolean nextPartWasPreloaded;
|
||||
|
||||
protected long lastProgressUpdateTime;
|
||||
|
||||
private ArrayList<Range> notLoadedBytesRanges;
|
||||
private volatile ArrayList<Range> notLoadedBytesRangesCopy;
|
||||
private ArrayList<Range> notRequestedBytesRanges;
|
||||
|
|
|
@ -28,12 +28,12 @@ import java.util.concurrent.CountDownLatch;
|
|||
public class FileLoader extends BaseController {
|
||||
|
||||
public interface FileLoaderDelegate {
|
||||
void fileUploadProgressChanged(String location, long uploadedSize, long totalSize, boolean isEncrypted);
|
||||
void fileUploadProgressChanged(FileUploadOperation operation, String location, long uploadedSize, long totalSize, boolean isEncrypted);
|
||||
void fileDidUploaded(String location, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile, byte[] key, byte[] iv, long totalFileSize);
|
||||
void fileDidFailedUpload(String location, boolean isEncrypted);
|
||||
void fileDidLoaded(String location, File finalFile, int type);
|
||||
void fileDidFailedLoad(String location, int state);
|
||||
void fileLoadProgressChanged(String location, long uploadedSize, long totalSize);
|
||||
void fileLoadProgressChanged(FileLoadOperation operation, String location, long uploadedSize, long totalSize);
|
||||
}
|
||||
|
||||
public static final int MEDIA_DIR_IMAGE = 0;
|
||||
|
@ -237,10 +237,10 @@ public class FileLoader extends BaseController {
|
|||
}
|
||||
|
||||
public void uploadFile(final String location, final boolean encrypted, final boolean small, final int type) {
|
||||
uploadFile(location, encrypted, small, 0, type);
|
||||
uploadFile(location, encrypted, small, 0, type, false);
|
||||
}
|
||||
|
||||
public void uploadFile(final String location, final boolean encrypted, final boolean small, final int estimatedSize, final int type) {
|
||||
public void uploadFile(final String location, final boolean encrypted, final boolean small, final int estimatedSize, final int type, boolean forceSmallFile) {
|
||||
if (location == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -262,15 +262,18 @@ public class FileLoader extends BaseController {
|
|||
uploadSizes.remove(location);
|
||||
}
|
||||
}
|
||||
if (delegate != null && estimatedSize != 0) {
|
||||
delegate.fileUploadProgressChanged(location, 0, estimatedSize, encrypted);
|
||||
}
|
||||
FileUploadOperation operation = new FileUploadOperation(currentAccount, location, encrypted, esimated, type);
|
||||
if (delegate != null && estimatedSize != 0) {
|
||||
delegate.fileUploadProgressChanged(operation, location, 0, estimatedSize, encrypted);
|
||||
}
|
||||
if (encrypted) {
|
||||
uploadOperationPathsEnc.put(location, operation);
|
||||
} else {
|
||||
uploadOperationPaths.put(location, operation);
|
||||
}
|
||||
if (forceSmallFile) {
|
||||
operation.setForceSmallFile();
|
||||
}
|
||||
operation.setDelegate(new FileUploadOperation.FileUploadOperationDelegate() {
|
||||
@Override
|
||||
public void didFinishUploadingFile(final FileUploadOperation operation, final TLRPC.InputFile inputFile, final TLRPC.InputEncryptedFile inputEncryptedFile, final byte[] key, final byte[] iv) {
|
||||
|
@ -341,7 +344,7 @@ public class FileLoader extends BaseController {
|
|||
@Override
|
||||
public void didChangedUploadProgress(FileUploadOperation operation, long uploadedSize, long totalSize) {
|
||||
if (delegate != null) {
|
||||
delegate.fileUploadProgressChanged(location, uploadedSize, totalSize, encrypted);
|
||||
delegate.fileUploadProgressChanged(operation, location, uploadedSize, totalSize, encrypted);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -715,7 +718,7 @@ public class FileLoader extends BaseController {
|
|||
@Override
|
||||
public void didChangedLoadProgress(FileLoadOperation operation, long uploadedSize, long totalSize) {
|
||||
if (delegate != null) {
|
||||
delegate.fileLoadProgressChanged(fileName, uploadedSize, totalSize);
|
||||
delegate.fileLoadProgressChanged(operation, fileName, uploadedSize, totalSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -67,6 +67,7 @@ public class FileUploadOperation {
|
|||
private boolean isEncrypted;
|
||||
private int fingerprint;
|
||||
private boolean isBigFile;
|
||||
private boolean forceSmallFile;
|
||||
private String fileKey;
|
||||
private int estimatedSize;
|
||||
private int uploadStartTime;
|
||||
|
@ -79,6 +80,7 @@ public class FileUploadOperation {
|
|||
private long availableSize;
|
||||
private boolean uploadFirstPartLater;
|
||||
private SparseArray<UploadCachedResult> cachedResults = new SparseArray<>();
|
||||
protected long lastProgressUpdateTime;
|
||||
|
||||
public interface FileUploadOperationDelegate {
|
||||
void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile, byte[] key, byte[] iv);
|
||||
|
@ -236,6 +238,10 @@ public class FileUploadOperation {
|
|||
}
|
||||
}
|
||||
|
||||
public void setForceSmallFile() {
|
||||
forceSmallFile = true;
|
||||
}
|
||||
|
||||
private void startUploadRequest() {
|
||||
if (state != 1) {
|
||||
return;
|
||||
|
@ -272,7 +278,7 @@ public class FileUploadOperation {
|
|||
} else {
|
||||
totalFileSize = cacheFile.length();
|
||||
}
|
||||
if (totalFileSize > 10 * 1024 * 1024) {
|
||||
if (!forceSmallFile && totalFileSize > 10 * 1024 * 1024) {
|
||||
isBigFile = true;
|
||||
}
|
||||
|
||||
|
@ -628,7 +634,7 @@ public class FileUploadOperation {
|
|||
if (currentUploadRequetsCount < maxRequestsCount) {
|
||||
startUploadRequest();
|
||||
}
|
||||
}), 0, ConnectionsManager.DEFAULT_DATACENTER_ID, connectionType, true);
|
||||
}), forceSmallFile ? ConnectionsManager.RequestFlagCanCompress : 0, ConnectionsManager.DEFAULT_DATACENTER_ID, connectionType, true);
|
||||
requestTokens.put(requestNumFinal, requestToken);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.net.Uri;
|
|||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.TextUtils;
|
||||
import android.util.SparseArray;
|
||||
|
@ -104,7 +105,6 @@ public class ImageLoader {
|
|||
|
||||
private volatile long lastCacheOutTime = 0;
|
||||
private int lastImageNum = 0;
|
||||
private long lastProgressUpdateTime = 0;
|
||||
|
||||
private File telegramPath = null;
|
||||
|
||||
|
@ -143,7 +143,7 @@ public class ImageLoader {
|
|||
}
|
||||
|
||||
private void reportProgress(long uploadedSize, long totalSize) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long currentTime = SystemClock.elapsedRealtime();
|
||||
if (uploadedSize == totalSize || lastProgressTime == 0 || lastProgressTime < currentTime - 100) {
|
||||
lastProgressTime = currentTime;
|
||||
Utilities.stageQueue.postRunnable(() -> {
|
||||
|
@ -441,7 +441,7 @@ public class ImageLoader {
|
|||
}
|
||||
|
||||
private void reportProgress(long uploadedSize, long totalSize) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long currentTime = SystemClock.elapsedRealtime();
|
||||
if (uploadedSize == totalSize || lastProgressTime == 0 || lastProgressTime < currentTime - 100) {
|
||||
lastProgressTime = currentTime;
|
||||
Utilities.stageQueue.postRunnable(() -> {
|
||||
|
@ -1074,7 +1074,7 @@ public class ImageLoader {
|
|||
|
||||
if (cacheImage.type == ImageReceiver.TYPE_THUMB) {
|
||||
try {
|
||||
lastCacheOutTime = System.currentTimeMillis();
|
||||
lastCacheOutTime = SystemClock.elapsedRealtime();
|
||||
synchronized (sync) {
|
||||
if (isCancelled) {
|
||||
return;
|
||||
|
@ -1179,10 +1179,10 @@ public class ImageLoader {
|
|||
if (mediaId != null) {
|
||||
delay = 0;
|
||||
}
|
||||
if (delay != 0 && lastCacheOutTime != 0 && lastCacheOutTime > System.currentTimeMillis() - delay && Build.VERSION.SDK_INT < 21) {
|
||||
if (delay != 0 && lastCacheOutTime != 0 && lastCacheOutTime > SystemClock.elapsedRealtime() - delay && Build.VERSION.SDK_INT < 21) {
|
||||
Thread.sleep(delay);
|
||||
}
|
||||
lastCacheOutTime = System.currentTimeMillis();
|
||||
lastCacheOutTime = SystemClock.elapsedRealtime();
|
||||
synchronized (sync) {
|
||||
if (isCancelled) {
|
||||
return;
|
||||
|
@ -1674,11 +1674,11 @@ public class ImageLoader {
|
|||
final int currentAccount = a;
|
||||
FileLoader.getInstance(a).setDelegate(new FileLoader.FileLoaderDelegate() {
|
||||
@Override
|
||||
public void fileUploadProgressChanged(final String location, long uploadedSize, long totalSize, final boolean isEncrypted) {
|
||||
public void fileUploadProgressChanged(FileUploadOperation operation, final String location, long uploadedSize, long totalSize, final boolean isEncrypted) {
|
||||
fileProgresses.put(location, new long[]{uploadedSize, totalSize});
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (lastProgressUpdateTime == 0 || lastProgressUpdateTime < currentTime - 500) {
|
||||
lastProgressUpdateTime = currentTime;
|
||||
long currentTime = SystemClock.elapsedRealtime();
|
||||
if (operation.lastProgressUpdateTime == 0 || operation.lastProgressUpdateTime < currentTime - 100 || uploadedSize == totalSize) {
|
||||
operation.lastProgressUpdateTime = currentTime;
|
||||
|
||||
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.FileUploadProgressChanged, location, uploadedSize, totalSize, isEncrypted));
|
||||
}
|
||||
|
@ -1724,11 +1724,11 @@ public class ImageLoader {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void fileLoadProgressChanged(final String location, long uploadedSize, long totalSize) {
|
||||
public void fileLoadProgressChanged(FileLoadOperation operation, final String location, long uploadedSize, long totalSize) {
|
||||
fileProgresses.put(location, new long[]{uploadedSize, totalSize});
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (lastProgressUpdateTime == 0 || lastProgressUpdateTime < currentTime - 500 || uploadedSize == 0) {
|
||||
lastProgressUpdateTime = currentTime;
|
||||
long currentTime = SystemClock.elapsedRealtime();
|
||||
if (operation.lastProgressUpdateTime == 0 || operation.lastProgressUpdateTime < currentTime - 500 || uploadedSize == 0) {
|
||||
operation.lastProgressUpdateTime = currentTime;
|
||||
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.FileLoadProgressChanged, location, uploadedSize, totalSize));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* This is the source code of Telegram for Android v. 5.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2018.
|
||||
*/
|
||||
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
public class ImportingService extends Service implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
private NotificationCompat.Builder builder;
|
||||
|
||||
public ImportingService() {
|
||||
super();
|
||||
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
|
||||
NotificationCenter.getInstance(a).addObserver(this, NotificationCenter.historyImportProgressChanged);
|
||||
}
|
||||
}
|
||||
|
||||
public IBinder onBind(Intent arg2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
try {
|
||||
stopForeground(true);
|
||||
} catch (Throwable ignore) {
|
||||
|
||||
}
|
||||
NotificationManagerCompat.from(ApplicationLoader.applicationContext).cancel(5);
|
||||
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
|
||||
NotificationCenter.getInstance(a).removeObserver(this, NotificationCenter.historyImportProgressChanged);
|
||||
}
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("destroy import service");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didReceivedNotification(int id, int account, Object... args) {
|
||||
if (id == NotificationCenter.historyImportProgressChanged) {
|
||||
if (!hasImports()) {
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasImports() {
|
||||
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
|
||||
if (SendMessagesHelper.getInstance(a).isImportingHistory()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (!hasImports()) {
|
||||
stopSelf();
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("start import service");
|
||||
}
|
||||
if (builder == null) {
|
||||
NotificationsController.checkOtherNotificationsChannel();
|
||||
builder = new NotificationCompat.Builder(ApplicationLoader.applicationContext);
|
||||
builder.setSmallIcon(android.R.drawable.stat_sys_upload);
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
builder.setChannelId(NotificationsController.OTHER_NOTIFICATIONS_CHANNEL);
|
||||
builder.setContentTitle(LocaleController.getString("AppName", R.string.AppName));
|
||||
builder.setTicker(LocaleController.getString("ImporImportingService", R.string.ImporImportingService));
|
||||
builder.setContentText(LocaleController.getString("ImporImportingService", R.string.ImporImportingService));
|
||||
}
|
||||
builder.setProgress(100, 0, true);
|
||||
startForeground(5, builder.build());
|
||||
NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(5, builder.build());
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
}
|
|
@ -1694,6 +1694,17 @@ public class LocaleController {
|
|||
return "LOC_ERR";
|
||||
}
|
||||
|
||||
public static String formatImportedDate(long date) {
|
||||
try {
|
||||
date *= 1000;
|
||||
Date dt = new Date(date);
|
||||
return String.format("%1$s, %2$s", getInstance().formatterYear.format(dt), getInstance().formatterDay.format(dt));
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
return "LOC_ERR";
|
||||
}
|
||||
|
||||
public static String formatUserStatus(int currentAccount, TLRPC.User user, boolean[] isOnline) {
|
||||
if (user != null && user.status != null && user.status.expires == 0) {
|
||||
if (user.status instanceof TLRPC.TL_userStatusRecently) {
|
||||
|
|
|
@ -1064,7 +1064,7 @@ public class LocationController extends BaseController implements NotificationCe
|
|||
arg = address.getThoroughfare();
|
||||
if (!TextUtils.isEmpty(arg)) {
|
||||
if (nameBuilder.length() > 0) {
|
||||
nameBuilder.append(", ");
|
||||
nameBuilder.append(" ");
|
||||
}
|
||||
nameBuilder.append(arg);
|
||||
hasAny = true;
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
package org.telegram.messenger;
|
||||
|
||||
import android.Manifest;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.DownloadManager;
|
||||
|
@ -103,6 +106,13 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
public native byte[] getWaveform(String path);
|
||||
public native byte[] getWaveform2(short[] array, int length);
|
||||
|
||||
public boolean isBuffering() {
|
||||
if (audioPlayer != null) {
|
||||
return audioPlayer.isBuffering();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class AudioBuffer {
|
||||
public AudioBuffer(int capacity) {
|
||||
buffer = ByteBuffer.allocateDirect(capacity);
|
||||
|
@ -647,6 +657,16 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
}
|
||||
};
|
||||
|
||||
private float audioVolume;
|
||||
private ValueAnimator audioVolumeAnimator;
|
||||
private final ValueAnimator.AnimatorUpdateListener audioVolumeUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator valueAnimator) {
|
||||
audioVolume = (float) valueAnimator.getAnimatedValue();
|
||||
setPlayerVolume();
|
||||
}
|
||||
};
|
||||
|
||||
private class InternalObserver extends ContentObserver {
|
||||
public InternalObserver() {
|
||||
super(null);
|
||||
|
@ -992,7 +1012,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
volume = VOLUME_DUCK;
|
||||
}
|
||||
if (audioPlayer != null) {
|
||||
audioPlayer.setVolume(volume);
|
||||
audioPlayer.setVolume(volume * audioVolume);
|
||||
} else if (videoPlayer != null) {
|
||||
videoPlayer.setVolume(volume);
|
||||
}
|
||||
|
@ -1769,10 +1789,41 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
|
||||
public void cleanupPlayer(boolean notify, boolean stopService, boolean byVoiceEnd, boolean transferPlayerToPhotoViewer) {
|
||||
if (audioPlayer != null) {
|
||||
try {
|
||||
audioPlayer.releasePlayer(true);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
if (audioVolumeAnimator != null) {
|
||||
audioVolumeAnimator.removeAllUpdateListeners();
|
||||
audioVolumeAnimator.cancel();
|
||||
}
|
||||
|
||||
if (audioPlayer.isPlaying() && playingMessageObject != null && !playingMessageObject.isVoice()) {
|
||||
VideoPlayer playerFinal = audioPlayer;
|
||||
ValueAnimator valueAnimator = ValueAnimator.ofFloat(audioVolume, 0);
|
||||
valueAnimator.addUpdateListener(valueAnimator1 -> {
|
||||
float volume;
|
||||
if (audioFocus != AUDIO_NO_FOCUS_CAN_DUCK) {
|
||||
volume = VOLUME_NORMAL;
|
||||
} else {
|
||||
volume = VOLUME_DUCK;
|
||||
}
|
||||
playerFinal.setVolume(volume * (float) valueAnimator1.getAnimatedValue());
|
||||
});
|
||||
valueAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
try {
|
||||
playerFinal.releasePlayer(true);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
valueAnimator.setDuration(300);
|
||||
valueAnimator.start();
|
||||
} else {
|
||||
try {
|
||||
audioPlayer.releasePlayer(true);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
audioPlayer = null;
|
||||
Theme.unrefAudioVisualizeDrawable(playingMessageObject);
|
||||
|
@ -1910,6 +1961,12 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
return true;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
if (audioPlayer == null) {
|
||||
return 0;
|
||||
}
|
||||
return audioPlayer.getDuration();
|
||||
}
|
||||
public MessageObject getPlayingMessageObject() {
|
||||
return playingMessageObject;
|
||||
}
|
||||
|
@ -2431,6 +2488,19 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
|
||||
public void setPlaybackSpeed(boolean music, float speed) {
|
||||
if (music) {
|
||||
if (currentMusicPlaybackSpeed >= 6 && speed == 1f && playingMessageObject != null) {
|
||||
audioPlayer.pause();
|
||||
float p = playingMessageObject.audioProgress;
|
||||
final MessageObject currentMessage = playingMessageObject;
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (audioPlayer != null && playingMessageObject != null && !isPaused) {
|
||||
if (isSamePlayingMessage(currentMessage )) {
|
||||
seekToProgress(playingMessageObject, p);
|
||||
}
|
||||
audioPlayer.play();
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
currentMusicPlaybackSpeed = speed;
|
||||
} else {
|
||||
currentPlaybackSpeed = speed;
|
||||
|
@ -3058,6 +3128,19 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
}
|
||||
audioPlayer.setStreamType(useFrontSpeaker ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
|
||||
audioPlayer.play();
|
||||
if (!messageObject.isVoice()) {
|
||||
if (audioVolumeAnimator != null) {
|
||||
audioVolumeAnimator.removeAllListeners();
|
||||
audioVolumeAnimator.cancel();
|
||||
}
|
||||
audioVolumeAnimator = ValueAnimator.ofFloat(audioVolume, 1f);
|
||||
audioVolumeAnimator.addUpdateListener(audioVolumeUpdateListener);
|
||||
audioVolumeAnimator.setDuration(300);
|
||||
audioVolumeAnimator.start();
|
||||
} else {
|
||||
audioVolume = 1f;
|
||||
setPlayerVolume();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
NotificationCenter.getInstance(messageObject.currentAccount).postNotificationName(NotificationCenter.messagePlayingPlayStateChanged, playingMessageObject != null ? playingMessageObject.getId() : 0);
|
||||
|
@ -3181,7 +3264,26 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
stopProgressTimer();
|
||||
try {
|
||||
if (audioPlayer != null) {
|
||||
audioPlayer.pause();
|
||||
if (!playingMessageObject.isVoice()) {
|
||||
if (audioVolumeAnimator != null) {
|
||||
audioVolumeAnimator.removeAllUpdateListeners();
|
||||
audioVolumeAnimator.cancel();
|
||||
}
|
||||
audioVolumeAnimator = ValueAnimator.ofFloat(1f, 0);
|
||||
audioVolumeAnimator.addUpdateListener(audioVolumeUpdateListener);
|
||||
audioVolumeAnimator.setDuration(300);
|
||||
audioVolumeAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (audioPlayer != null) {
|
||||
audioPlayer.pause();
|
||||
}
|
||||
}
|
||||
});
|
||||
audioVolumeAnimator.start();
|
||||
} else {
|
||||
audioPlayer.pause();
|
||||
}
|
||||
} else if (videoPlayer != null) {
|
||||
videoPlayer.pause();
|
||||
}
|
||||
|
@ -3202,6 +3304,19 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
|
||||
try {
|
||||
startProgressTimer(playingMessageObject);
|
||||
if (audioVolumeAnimator != null) {
|
||||
audioVolumeAnimator.removeAllListeners();
|
||||
audioVolumeAnimator.cancel();
|
||||
}
|
||||
if (!messageObject.isVoice()) {
|
||||
audioVolumeAnimator = ValueAnimator.ofFloat(audioVolume, 1f);
|
||||
audioVolumeAnimator.addUpdateListener(audioVolumeUpdateListener);
|
||||
audioVolumeAnimator.setDuration(300);
|
||||
audioVolumeAnimator.start();
|
||||
} else {
|
||||
audioVolume = 1f;
|
||||
setPlayerVolume();
|
||||
}
|
||||
if (audioPlayer != null) {
|
||||
audioPlayer.play();
|
||||
} else if (videoPlayer != null) {
|
||||
|
@ -4400,6 +4515,25 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
});
|
||||
}
|
||||
|
||||
public void pauseByRewind() {
|
||||
if (audioPlayer != null) {
|
||||
audioPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public void resumeByRewind() {
|
||||
if (audioPlayer != null && playingMessageObject != null && !isPaused) {
|
||||
if (audioPlayer.isBuffering()) {
|
||||
MessageObject currentMessageObject = playingMessageObject;
|
||||
cleanupPlayer(false, false);
|
||||
playMessage(currentMessageObject);
|
||||
} else {
|
||||
audioPlayer.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class VideoConvertRunnable implements Runnable {
|
||||
|
||||
private VideoConvertMessage convertMessage;
|
||||
|
|
|
@ -2153,6 +2153,10 @@ public class MediaDataController extends BaseController {
|
|||
messagesSearchEndReached[1] = res.messages.isEmpty();
|
||||
messagesSearchCount[1] = res instanceof TLRPC.TL_messages_messagesSlice ? res.count : res.messages.size();
|
||||
searchMessagesInChat(req.q, dialogId, mergeDialogId, guid, direction, replyMessageId, true, user, chat, jumpToMessage);
|
||||
} else {
|
||||
messagesSearchEndReached[1] = true;
|
||||
messagesSearchCount[1] = 0;
|
||||
searchMessagesInChat(req.q, dialogId, mergeDialogId, guid, direction, replyMessageId, true, user, chat, jumpToMessage);
|
||||
}
|
||||
}
|
||||
}), ConnectionsManager.RequestFlagFailOnServerErrors);
|
||||
|
|
|
@ -5315,7 +5315,7 @@ public class MessageObject {
|
|||
}
|
||||
|
||||
public boolean needDrawForwarded() {
|
||||
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_FWD) != 0 && messageOwner.fwd_from != null && (messageOwner.fwd_from.saved_from_peer == null || messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerChannel && messageOwner.fwd_from.saved_from_peer.channel_id != messageOwner.fwd_from.from_id.channel_id) && UserConfig.getInstance(currentAccount).getClientUserId() != getDialogId();
|
||||
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_FWD) != 0 && messageOwner.fwd_from != null && !messageOwner.fwd_from.imported && (messageOwner.fwd_from.saved_from_peer == null || messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerChannel && messageOwner.fwd_from.saved_from_peer.channel_id != messageOwner.fwd_from.from_id.channel_id) && UserConfig.getInstance(currentAccount).getClientUserId() != getDialogId();
|
||||
}
|
||||
|
||||
public static boolean isForwardedMessage(TLRPC.Message message) {
|
||||
|
@ -5551,6 +5551,10 @@ public class MessageObject {
|
|||
return messageOwner.fwd_from != null && !TextUtils.isEmpty(messageOwner.fwd_from.from_name);
|
||||
}
|
||||
|
||||
public boolean isImportedForward() {
|
||||
return messageOwner.fwd_from != null && messageOwner.fwd_from.imported;
|
||||
}
|
||||
|
||||
public int getSenderId() {
|
||||
if (messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null) {
|
||||
if (messageOwner.fwd_from.saved_from_peer.user_id != 0) {
|
||||
|
|
|
@ -65,7 +65,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
|
||||
private ArrayList<Integer> joiningToChannels = new ArrayList<>();
|
||||
|
||||
private SparseArray<TLRPC.ExportedChatInvite> exportedChats = new SparseArray<>();
|
||||
private SparseArray<TLRPC.TL_chatInviteExported> exportedChats = new SparseArray<>();
|
||||
|
||||
public ArrayList<TLRPC.RecentMeUrl> hintDialogs = new ArrayList<>();
|
||||
private SparseArray<ArrayList<TLRPC.Dialog>> dialogsByFolder = new SparseArray<>();
|
||||
|
@ -287,7 +287,11 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
public boolean saveGifsWithStickers;
|
||||
private String installReferer;
|
||||
public Set<String> pendingSuggestions;
|
||||
public Set<String> exportUri;
|
||||
public Set<String> exportGroupUri;
|
||||
public Set<String> exportPrivateUri;
|
||||
public boolean autoarchiveAvailable;
|
||||
public boolean suggestStickersApiOnly;
|
||||
public ArrayList<String> gifSearchEmojies = new ArrayList<>();
|
||||
public HashSet<String> diceEmojies;
|
||||
public HashMap<String, DiceFrameSuccess> diceSuccess = new HashMap<>();
|
||||
|
@ -717,6 +721,8 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
filtersEnabled = mainPreferences.getBoolean("filtersEnabled", false);
|
||||
showFiltersTooltip = mainPreferences.getBoolean("showFiltersTooltip", false);
|
||||
autoarchiveAvailable = mainPreferences.getBoolean("autoarchiveAvailable", false);
|
||||
suggestStickersApiOnly = mainPreferences.getBoolean("suggestStickersApiOnly", false);
|
||||
|
||||
pendingSuggestions = mainPreferences.getStringSet("pendingSuggestions", null);
|
||||
if (pendingSuggestions != null) {
|
||||
pendingSuggestions = new HashSet<>(pendingSuggestions);
|
||||
|
@ -724,6 +730,30 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
pendingSuggestions = new HashSet<>();
|
||||
}
|
||||
|
||||
exportUri = mainPreferences.getStringSet("exportUri", null);
|
||||
if (exportUri != null) {
|
||||
exportUri = new HashSet<>(exportUri);
|
||||
} else {
|
||||
exportUri = new HashSet<>();
|
||||
exportUri.add("content://com.whatsapp.provider.media/export_chat/");
|
||||
}
|
||||
|
||||
exportGroupUri = mainPreferences.getStringSet("exportGroupUri", null);
|
||||
if (exportGroupUri != null) {
|
||||
exportGroupUri = new HashSet<>(exportGroupUri);
|
||||
} else {
|
||||
exportGroupUri = new HashSet<>();
|
||||
exportGroupUri.add("@g.us/");
|
||||
}
|
||||
|
||||
exportPrivateUri = mainPreferences.getStringSet("exportPrivateUri", null);
|
||||
if (exportPrivateUri != null) {
|
||||
exportPrivateUri = new HashSet<>(exportPrivateUri);
|
||||
} else {
|
||||
exportPrivateUri = new HashSet<>();
|
||||
exportPrivateUri.add("@s.whatsapp.net/");
|
||||
}
|
||||
|
||||
Set<String> emojies = mainPreferences.getStringSet("diceEmojies", null);
|
||||
if (emojies == null) {
|
||||
diceEmojies = new HashSet<>();
|
||||
|
@ -1452,6 +1482,74 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "stickers_emoji_suggest_only_api": {
|
||||
if (value.value instanceof TLRPC.TL_jsonBool) {
|
||||
TLRPC.TL_jsonBool bool = (TLRPC.TL_jsonBool) value.value;
|
||||
if (bool.value != suggestStickersApiOnly) {
|
||||
suggestStickersApiOnly = bool.value;
|
||||
editor.putBoolean("suggestStickersApiOnly", suggestStickersApiOnly);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "export_urls": {
|
||||
HashSet<String> newExport = new HashSet<>();
|
||||
if (value.value instanceof TLRPC.TL_jsonArray) {
|
||||
TLRPC.TL_jsonArray array = (TLRPC.TL_jsonArray) value.value;
|
||||
for (int b = 0, N2 = array.value.size(); b < N2; b++) {
|
||||
TLRPC.JSONValue val = array.value.get(b);
|
||||
if (val instanceof TLRPC.TL_jsonString) {
|
||||
TLRPC.TL_jsonString string = (TLRPC.TL_jsonString) val;
|
||||
newExport.add(string.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!exportUri.equals(newExport)) {
|
||||
exportUri = newExport;
|
||||
editor.putStringSet("exportUri", exportUri);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "export_group_urls": {
|
||||
HashSet<String> newExport = new HashSet<>();
|
||||
if (value.value instanceof TLRPC.TL_jsonArray) {
|
||||
TLRPC.TL_jsonArray array = (TLRPC.TL_jsonArray) value.value;
|
||||
for (int b = 0, N2 = array.value.size(); b < N2; b++) {
|
||||
TLRPC.JSONValue val = array.value.get(b);
|
||||
if (val instanceof TLRPC.TL_jsonString) {
|
||||
TLRPC.TL_jsonString string = (TLRPC.TL_jsonString) val;
|
||||
newExport.add(string.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!exportGroupUri.equals(newExport)) {
|
||||
exportGroupUri = newExport;
|
||||
editor.putStringSet("exportGroupUri", exportGroupUri);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "export_private_urls": {
|
||||
HashSet<String> newExport = new HashSet<>();
|
||||
if (value.value instanceof TLRPC.TL_jsonArray) {
|
||||
TLRPC.TL_jsonArray array = (TLRPC.TL_jsonArray) value.value;
|
||||
for (int b = 0, N2 = array.value.size(); b < N2; b++) {
|
||||
TLRPC.JSONValue val = array.value.get(b);
|
||||
if (val instanceof TLRPC.TL_jsonString) {
|
||||
TLRPC.TL_jsonString string = (TLRPC.TL_jsonString) val;
|
||||
newExport.add(string.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!exportPrivateUri.equals(newExport)) {
|
||||
exportPrivateUri = newExport;
|
||||
editor.putStringSet("exportPrivateUri", exportPrivateUri);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "pending_suggestions": {
|
||||
HashSet<String> newSuggestions = new HashSet<>();
|
||||
if (value.value instanceof TLRPC.TL_jsonArray) {
|
||||
|
@ -2430,7 +2528,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
});
|
||||
}
|
||||
|
||||
public TLRPC.ExportedChatInvite getExportedInvite(int chat_id) {
|
||||
public TLRPC.TL_chatInviteExported getExportedInvite(int chat_id) {
|
||||
return exportedChats.get(chat_id);
|
||||
}
|
||||
|
||||
|
@ -2461,12 +2559,14 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
oldUser.username = null;
|
||||
}
|
||||
}
|
||||
if (user.photo != null) {
|
||||
oldUser.photo = user.photo;
|
||||
oldUser.flags |= 32;
|
||||
} else {
|
||||
oldUser.flags = oldUser.flags &~ 32;
|
||||
oldUser.photo = null;
|
||||
if (user.apply_min_photo) {
|
||||
if (user.photo != null) {
|
||||
oldUser.photo = user.photo;
|
||||
oldUser.flags |= 32;
|
||||
} else {
|
||||
oldUser.flags = oldUser.flags & ~32;
|
||||
oldUser.photo = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2485,7 +2585,6 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
} else if (oldUser == null) {
|
||||
users.put(user.id, user);
|
||||
} else if (oldUser.min) {
|
||||
user.min = false;
|
||||
if (oldUser.bot) {
|
||||
if (oldUser.username != null) {
|
||||
user.username = oldUser.username;
|
||||
|
@ -2495,12 +2594,14 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
user.username = null;
|
||||
}
|
||||
}
|
||||
if (oldUser.photo != null) {
|
||||
user.photo = oldUser.photo;
|
||||
user.flags |= 32;
|
||||
} else {
|
||||
user.flags = user.flags &~ 32;
|
||||
user.photo = null;
|
||||
if (oldUser.apply_min_photo) {
|
||||
if (oldUser.photo != null) {
|
||||
user.photo = oldUser.photo;
|
||||
user.flags |= 32;
|
||||
} else {
|
||||
user.flags = user.flags & ~32;
|
||||
user.photo = null;
|
||||
}
|
||||
}
|
||||
users.put(user.id, user);
|
||||
}
|
||||
|
@ -2616,7 +2717,6 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
} else if (oldChat == null) {
|
||||
chats.put(chat.id, chat);
|
||||
} else if (oldChat.min) {
|
||||
chat.min = false;
|
||||
chat.title = oldChat.title;
|
||||
chat.photo = oldChat.photo;
|
||||
chat.broadcast = oldChat.broadcast;
|
||||
|
@ -2786,12 +2886,6 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
ArrayList<TLRPC.Update> arrayList = new ArrayList<>();
|
||||
for (int a = 0; a < res.dialogs.size(); a++) {
|
||||
TLRPC.Dialog dialog = res.dialogs.get(a);
|
||||
if (dialog.read_inbox_max_id == 0) {
|
||||
dialog.read_inbox_max_id = 1;
|
||||
}
|
||||
if (dialog.read_outbox_max_id == 0) {
|
||||
dialog.read_outbox_max_id = 1;
|
||||
}
|
||||
DialogObject.initDialog(dialog);
|
||||
|
||||
Integer value = dialogs_read_inbox_max.get(dialog.id);
|
||||
|
@ -3066,7 +3160,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
users.add(userFull.user);
|
||||
putUsers(users, false);
|
||||
getMessagesStorage().putUsersAndChats(users, null, false, true);
|
||||
if (names != null && !names.equals(userFull.user.first_name + userFull.user.last_name + userFull.user.username)) {
|
||||
if (!names.equals(userFull.user.first_name + userFull.user.last_name + userFull.user.username)) {
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_NAME);
|
||||
}
|
||||
if (userFull.bot_info instanceof TLRPC.TL_botInfo) {
|
||||
|
@ -3200,12 +3294,13 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
SharedPreferences.Editor editor = notificationsPreferences.edit();
|
||||
editor.putInt("dialog_bar_vis3" + dialogId, 3);
|
||||
editor.remove("dialog_bar_invite" + dialogId);
|
||||
editor.commit();
|
||||
if ((int) dialogId != 0) {
|
||||
TLRPC.TL_messages_hidePeerSettingsBar req = new TLRPC.TL_messages_hidePeerSettingsBar();
|
||||
if (currentUser != null) {
|
||||
req.peer = getInputPeer(currentUser.id);
|
||||
} else if (currentChat != null) {
|
||||
} else {
|
||||
req.peer = getInputPeer(-currentChat.id);
|
||||
}
|
||||
getConnectionsManager().sendRequest(req, (response, error) -> {
|
||||
|
@ -3263,9 +3358,9 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
return;
|
||||
}
|
||||
SharedPreferences.Editor editor = notificationsPreferences.edit();
|
||||
boolean bar_hidden = !settings.report_spam && !settings.add_contact && !settings.block_contact && !settings.share_contact && !settings.report_geo;
|
||||
boolean bar_hidden = !settings.report_spam && !settings.add_contact && !settings.block_contact && !settings.share_contact && !settings.report_geo && !settings.invite_members;
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("peer settings loaded for " + dialogId + " add = " + settings.add_contact + " block = " + settings.block_contact + " spam = " + settings.report_spam + " share = " + settings.share_contact + " geo = " + settings.report_geo + " hide = " + bar_hidden + " distance = " + settings.geo_distance);
|
||||
FileLog.d("peer settings loaded for " + dialogId + " add = " + settings.add_contact + " block = " + settings.block_contact + " spam = " + settings.report_spam + " share = " + settings.share_contact + " geo = " + settings.report_geo + " hide = " + bar_hidden + " distance = " + settings.geo_distance + " invite = " + settings.invite_members);
|
||||
}
|
||||
editor.putInt("dialog_bar_vis3" + dialogId, bar_hidden ? 1 : 2);
|
||||
editor.putBoolean("dialog_bar_share" + dialogId, settings.share_contact);
|
||||
|
@ -3275,6 +3370,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
editor.putBoolean("dialog_bar_exception" + dialogId, settings.need_contacts_exception);
|
||||
editor.putBoolean("dialog_bar_location" + dialogId, settings.report_geo);
|
||||
editor.putBoolean("dialog_bar_archived" + dialogId, settings.autoarchived);
|
||||
editor.putBoolean("dialog_bar_invite" + dialogId, settings.invite_members);
|
||||
if (notificationsPreferences.getInt("dialog_bar_distance" + dialogId, -1) != -2) {
|
||||
if ((settings.flags & 64) != 0) {
|
||||
editor.putInt("dialog_bar_distance" + dialogId, settings.geo_distance);
|
||||
|
@ -3313,7 +3409,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
TLRPC.TL_messages_getPeerSettings req = new TLRPC.TL_messages_getPeerSettings();
|
||||
if (currentUser != null) {
|
||||
req.peer = getInputPeer(currentUser.id);
|
||||
} else if (currentChat != null) {
|
||||
} else {
|
||||
req.peer = getInputPeer(-currentChat.id);
|
||||
}
|
||||
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
|
@ -3368,7 +3464,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
}
|
||||
|
||||
protected void processNewDifferenceParams(int seq, int pts, int date, int pts_count) {
|
||||
public void processNewDifferenceParams(int seq, int pts, int date, int pts_count) {
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("processNewDifferenceParams seq = " + seq + " pts = " + pts + " date = " + date + " pts_count = " + pts_count);
|
||||
}
|
||||
|
@ -4338,7 +4434,10 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
if (first == 1 && max_id == 0) {
|
||||
TLRPC.InputPeer peerFinal = peer;
|
||||
getMessagesStorage().getDialogMaxMessageId(did, (param) -> deleteDialog(did, 2, onlyHistory, Math.max(0, param), revoke, peerFinal, taskId));
|
||||
getMessagesStorage().getDialogMaxMessageId(did, (param) -> {
|
||||
deleteDialog(did, 2, onlyHistory, Math.max(0, param), revoke, peerFinal, taskId);
|
||||
checkIfFolderEmpty(1);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (onlyHistory == 0 || onlyHistory == 3) {
|
||||
|
@ -4351,6 +4450,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
if (first != 0) {
|
||||
boolean isPromoDialog = false;
|
||||
getMessagesStorage().deleteDialog(did, onlyHistory);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.dialogDeleted, did);
|
||||
TLRPC.Dialog dialog = dialogs_dict.get(did);
|
||||
if (onlyHistory == 0 || onlyHistory == 3) {
|
||||
getNotificationsController().deleteNotificationChannel(did);
|
||||
|
@ -4545,7 +4645,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
if (onlyHistory == 1) {
|
||||
getSecretChatHelper().sendClearHistoryMessage(getEncryptedChat(high_id), null);
|
||||
} else {
|
||||
getSecretChatHelper().declineSecretChat(high_id);
|
||||
getSecretChatHelper().declineSecretChat(high_id, revoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7097,7 +7197,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
channelsPts.put(-(int) d.id, d.pts);
|
||||
} else if ((int) d.id < 0) {
|
||||
TLRPC.Chat chat = chatsDict.get(-(int) d.id);
|
||||
if (chat != null && chat.migrated_to != null) {
|
||||
if (chat != null && (chat.migrated_to != null || ChatObject.isNotInChat(chat))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -7676,7 +7776,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
} else if (message.peer_id.chat_id != 0) {
|
||||
TLRPC.Chat chat = chatsDict.get(message.peer_id.chat_id);
|
||||
if (chat != null && chat.migrated_to != null) {
|
||||
if (chat != null && (chat.migrated_to != null || ChatObject.isNotInChat(chat))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -7695,7 +7795,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
} else if ((int) d.id < 0) {
|
||||
TLRPC.Chat chat = chatsDict.get(-(int) d.id);
|
||||
if (chat != null && chat.migrated_to != null) {
|
||||
if (chat != null && (chat.migrated_to != null || ChatObject.isNotInChat(chat))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -8315,8 +8415,8 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
}
|
||||
|
||||
public int createChat(String title, ArrayList<Integer> selectedContacts, final String about, int type, Location location, String locationAddress, final BaseFragment fragment) {
|
||||
if (type == ChatObject.CHAT_TYPE_CHAT) {
|
||||
public int createChat(String title, ArrayList<Integer> selectedContacts, final String about, int type, boolean forImport, Location location, String locationAddress, final BaseFragment fragment) {
|
||||
if (type == ChatObject.CHAT_TYPE_CHAT && !forImport) {
|
||||
final TLRPC.TL_messages_createChat req = new TLRPC.TL_messages_createChat();
|
||||
req.title = title;
|
||||
for (int a = 0; a < selectedContacts.size(); a++) {
|
||||
|
@ -8346,11 +8446,12 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
});
|
||||
}, ConnectionsManager.RequestFlagFailOnServerErrors);
|
||||
} else if (type == ChatObject.CHAT_TYPE_CHANNEL || type == ChatObject.CHAT_TYPE_MEGAGROUP) {
|
||||
} else if (forImport || type == ChatObject.CHAT_TYPE_CHANNEL || type == ChatObject.CHAT_TYPE_MEGAGROUP) {
|
||||
final TLRPC.TL_channels_createChannel req = new TLRPC.TL_channels_createChannel();
|
||||
req.title = title;
|
||||
req.about = about != null ? about : "";
|
||||
if (type == ChatObject.CHAT_TYPE_MEGAGROUP) {
|
||||
req.for_import = forImport;
|
||||
if (forImport || type == ChatObject.CHAT_TYPE_MEGAGROUP) {
|
||||
req.megagroup = true;
|
||||
} else {
|
||||
req.broadcast = true;
|
||||
|
@ -8389,18 +8490,20 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
public void convertToMegaGroup(final Context context, int chat_id, BaseFragment fragment, MessagesStorage.IntCallback convertRunnable) {
|
||||
TLRPC.TL_messages_migrateChat req = new TLRPC.TL_messages_migrateChat();
|
||||
req.chat_id = chat_id;
|
||||
final AlertDialog progressDialog = new AlertDialog(context, 3);
|
||||
final AlertDialog progressDialog = context != null ? new AlertDialog(context, 3) : null;
|
||||
final int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
|
||||
if (error == null) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (!((Activity) context).isFinishing()) {
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
if (context != null) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (!((Activity) context).isFinishing()) {
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
TLRPC.Updates updates = (TLRPC.Updates) response;
|
||||
processUpdates((TLRPC.Updates) response, false);
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
|
@ -8419,22 +8522,26 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
if (convertRunnable != null) {
|
||||
convertRunnable.run(0);
|
||||
}
|
||||
if (!((Activity) context).isFinishing()) {
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
if (context != null) {
|
||||
if (!((Activity) context).isFinishing()) {
|
||||
try {
|
||||
progressDialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
AlertsCreator.processError(currentAccount, error, fragment, req, false);
|
||||
}
|
||||
AlertsCreator.processError(currentAccount, error, fragment, req, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
progressDialog.setOnCancelListener(dialog -> getConnectionsManager().cancelRequest(reqId, true));
|
||||
try {
|
||||
progressDialog.show();
|
||||
} catch (Exception e) {
|
||||
//don't promt
|
||||
if (progressDialog != null) {
|
||||
progressDialog.setOnCancelListener(dialog -> getConnectionsManager().cancelRequest(reqId, true));
|
||||
try {
|
||||
progressDialog.show();
|
||||
} catch (Exception e) {
|
||||
//don't promt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8635,84 +8742,68 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
if (chat_id > 0) {
|
||||
final TLRPC.InputUser inputUser = getInputUser(user);
|
||||
TLObject request;
|
||||
TLRPC.Chat chat = getChat(chat_id);
|
||||
final boolean isChannel = ChatObject.isChannel(chat);
|
||||
if (isChannel) {
|
||||
if (inputUser instanceof TLRPC.TL_inputUserSelf) {
|
||||
if (chat.creator && forceDelete) {
|
||||
TLRPC.TL_channels_deleteChannel req = new TLRPC.TL_channels_deleteChannel();
|
||||
req.channel = getInputChannel(chat);
|
||||
request = req;
|
||||
} else {
|
||||
TLRPC.TL_channels_leaveChannel req = new TLRPC.TL_channels_leaveChannel();
|
||||
req.channel = getInputChannel(chat);
|
||||
request = req;
|
||||
}
|
||||
} else {
|
||||
TLRPC.TL_channels_editBanned req = new TLRPC.TL_channels_editBanned();
|
||||
final TLRPC.InputUser inputUser = getInputUser(user);
|
||||
TLObject request;
|
||||
TLRPC.Chat chat = getChat(chat_id);
|
||||
final boolean isChannel = ChatObject.isChannel(chat);
|
||||
if (isChannel) {
|
||||
if (inputUser instanceof TLRPC.TL_inputUserSelf) {
|
||||
if (chat.creator && forceDelete) {
|
||||
TLRPC.TL_channels_deleteChannel req = new TLRPC.TL_channels_deleteChannel();
|
||||
req.channel = getInputChannel(chat);
|
||||
request = req;
|
||||
} else {
|
||||
TLRPC.TL_channels_leaveChannel req = new TLRPC.TL_channels_leaveChannel();
|
||||
req.channel = getInputChannel(chat);
|
||||
req.user_id = inputUser;
|
||||
req.banned_rights = new TLRPC.TL_chatBannedRights();
|
||||
req.banned_rights.view_messages = true;
|
||||
req.banned_rights.send_media = true;
|
||||
req.banned_rights.send_messages = true;
|
||||
req.banned_rights.send_stickers = true;
|
||||
req.banned_rights.send_gifs = true;
|
||||
req.banned_rights.send_games = true;
|
||||
req.banned_rights.send_inline = true;
|
||||
req.banned_rights.embed_links = true;
|
||||
req.banned_rights.pin_messages = true;
|
||||
req.banned_rights.send_polls = true;
|
||||
req.banned_rights.invite_users = true;
|
||||
req.banned_rights.change_info = true;
|
||||
request = req;
|
||||
}
|
||||
} else {
|
||||
TLRPC.TL_messages_deleteChatUser req = new TLRPC.TL_messages_deleteChatUser();
|
||||
req.chat_id = chat_id;
|
||||
req.user_id = getInputUser(user);
|
||||
TLRPC.TL_channels_editBanned req = new TLRPC.TL_channels_editBanned();
|
||||
req.channel = getInputChannel(chat);
|
||||
req.user_id = inputUser;
|
||||
req.banned_rights = new TLRPC.TL_chatBannedRights();
|
||||
req.banned_rights.view_messages = true;
|
||||
req.banned_rights.send_media = true;
|
||||
req.banned_rights.send_messages = true;
|
||||
req.banned_rights.send_stickers = true;
|
||||
req.banned_rights.send_gifs = true;
|
||||
req.banned_rights.send_games = true;
|
||||
req.banned_rights.send_inline = true;
|
||||
req.banned_rights.embed_links = true;
|
||||
req.banned_rights.pin_messages = true;
|
||||
req.banned_rights.send_polls = true;
|
||||
req.banned_rights.invite_users = true;
|
||||
req.banned_rights.change_info = true;
|
||||
request = req;
|
||||
}
|
||||
if (user.id == getUserConfig().getClientUserId()) {
|
||||
deleteDialog(-chat_id, 0, revoke);
|
||||
}
|
||||
getConnectionsManager().sendRequest(request, (response, error) -> {
|
||||
if (error != null) {
|
||||
return;
|
||||
}
|
||||
final TLRPC.Updates updates = (TLRPC.Updates) response;
|
||||
processUpdates(updates, false);
|
||||
if (isChannel && !(inputUser instanceof TLRPC.TL_inputUserSelf)) {
|
||||
AndroidUtilities.runOnUIThread(() -> loadFullChat(chat_id, 0, true), 1000);
|
||||
}
|
||||
}, ConnectionsManager.RequestFlagInvokeAfter);
|
||||
} else {
|
||||
if (info instanceof TLRPC.TL_chatFull) {
|
||||
TLRPC.Chat chat = getChat(chat_id);
|
||||
chat.participants_count--;
|
||||
ArrayList<TLRPC.Chat> chatArrayList = new ArrayList<>();
|
||||
chatArrayList.add(chat);
|
||||
getMessagesStorage().putUsersAndChats(null, chatArrayList, true, true);
|
||||
if (forceDelete) {
|
||||
TLRPC.TL_messages_deleteChat req = new TLRPC.TL_messages_deleteChat();
|
||||
req.chat_id = chat_id;
|
||||
getConnectionsManager().sendRequest(req, (response, error) -> {
|
||||
|
||||
boolean changed = false;
|
||||
for (int a = 0; a < info.participants.participants.size(); a++) {
|
||||
TLRPC.ChatParticipant p = info.participants.participants.get(a);
|
||||
if (p.user_id == user.id) {
|
||||
info.participants.participants.remove(a);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
getMessagesStorage().updateChatInfo(info, true);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.chatInfoDidLoad, info, 0, false);
|
||||
}
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT_MEMBERS);
|
||||
});
|
||||
return;
|
||||
}
|
||||
TLRPC.TL_messages_deleteChatUser req = new TLRPC.TL_messages_deleteChatUser();
|
||||
req.chat_id = chat_id;
|
||||
req.user_id = getInputUser(user);
|
||||
req.revoke_history = true;
|
||||
request = req;
|
||||
}
|
||||
if (user.id == getUserConfig().getClientUserId()) {
|
||||
deleteDialog(-chat_id, 0, revoke);
|
||||
}
|
||||
getConnectionsManager().sendRequest(request, (response, error) -> {
|
||||
if (error != null) {
|
||||
return;
|
||||
}
|
||||
final TLRPC.Updates updates = (TLRPC.Updates) response;
|
||||
processUpdates(updates, false);
|
||||
if (isChannel && !(inputUser instanceof TLRPC.TL_inputUserSelf)) {
|
||||
AndroidUtilities.runOnUIThread(() -> loadFullChat(chat_id, 0, true), 1000);
|
||||
}
|
||||
}, ConnectionsManager.RequestFlagInvokeAfter);
|
||||
}
|
||||
|
||||
public void changeChatTitle(int chat_id, String title) {
|
||||
|
@ -10987,6 +11078,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
SparseArray<ArrayList<Integer>> deletedMessages = null;
|
||||
SparseArray<ArrayList<Integer>> scheduledDeletedMessages = null;
|
||||
SparseArray<ArrayList<Integer>> groupSpeakingActions = null;
|
||||
LongSparseArray<Integer> importingActions = null;
|
||||
SparseIntArray clearHistoryMessages = null;
|
||||
ArrayList<TLRPC.ChatParticipants> chatInfoToUpdate = null;
|
||||
ArrayList<TLRPC.Update> updatesOnMainThread = null;
|
||||
|
@ -11338,11 +11430,17 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
action = update.action;
|
||||
threadId = 0;
|
||||
}
|
||||
if (userId != getUserConfig().getClientUserId()) {
|
||||
long uid = -chatId;
|
||||
if (uid == 0) {
|
||||
uid = userId;
|
||||
long uid = -chatId;
|
||||
if (uid == 0) {
|
||||
uid = userId;
|
||||
}
|
||||
if (action instanceof TLRPC.TL_sendMessageHistoryImportAction) {
|
||||
if (importingActions == null) {
|
||||
importingActions = new LongSparseArray<>();
|
||||
}
|
||||
TLRPC.TL_sendMessageHistoryImportAction importAction = (TLRPC.TL_sendMessageHistoryImportAction) action;
|
||||
importingActions.put(uid, importAction.progress);
|
||||
} else if (userId != getUserConfig().getClientUserId()) {
|
||||
if (action instanceof TLRPC.TL_speakingInGroupCallAction) {
|
||||
if (chatId != 0) {
|
||||
if (groupSpeakingActions == null) {
|
||||
|
@ -12099,6 +12197,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
final ArrayList<ImageLoader.MessageThumb> updateMessageThumbs = messageThumbs;
|
||||
final ArrayList<TLRPC.TL_updateFolderPeers> folderUpdatesFinal = folderUpdates;
|
||||
final SparseArray<ArrayList<Integer>> groupSpeakingActionsFinal = groupSpeakingActions;
|
||||
final LongSparseArray<Integer> importingActionsFinal = importingActions;
|
||||
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
int updateMask = interfaceUpdateMaskFinal;
|
||||
|
@ -12358,7 +12457,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
if (chat != null) {
|
||||
if (dialog == null && chat instanceof TLRPC.TL_channel && !chat.left) {
|
||||
Utilities.stageQueue.postRunnable(() -> getChannelDifference(update.channel_id, 1, 0, null));
|
||||
} else if (chat.left && dialog != null && (promoDialog == null || promoDialog.id != dialog.id)) {
|
||||
} else if (ChatObject.isNotInChat(chat) && dialog != null && (promoDialog == null || promoDialog.id != dialog.id)) {
|
||||
deleteDialog(dialog.id, 0);
|
||||
}
|
||||
if (chat instanceof TLRPC.TL_channelForbidden || chat.kicked) {
|
||||
|
@ -12394,6 +12493,10 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
VoIPService.getSharedInstance().onGroupCallUpdated(updateGroupCall.call);
|
||||
}
|
||||
}
|
||||
TLRPC.Dialog dialog = dialogs_dict.get(-chat.id);
|
||||
if (dialog != null) {
|
||||
deleteDialog(dialog.id, 0);
|
||||
}
|
||||
}
|
||||
updateMask |= UPDATE_MASK_CHAT;
|
||||
loadFullChat(update.chat_id, 0, true);
|
||||
|
@ -12647,6 +12750,16 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
}
|
||||
}
|
||||
if (importingActionsFinal != null) {
|
||||
for (int a = 0, N = importingActionsFinal.size(); a < N; a++) {
|
||||
long did = importingActionsFinal.keyAt(a);
|
||||
SendMessagesHelper.ImportingHistory importingHistory = getSendMessagesHelper().getImportingHistory(did);
|
||||
if (importingHistory == null) {
|
||||
continue;
|
||||
}
|
||||
importingHistory.setImportProgress(importingActionsFinal.valueAt(a));
|
||||
}
|
||||
}
|
||||
if (webPagesFinal != null) {
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.didReceivedWebpagesInUpdates, webPagesFinal);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
@ -13076,7 +13189,7 @@ public class MessagesController extends BaseController implements NotificationCe
|
|||
}
|
||||
if (message.messageOwner.action instanceof TLRPC.TL_messageActionGroupCall) {
|
||||
TLRPC.ChatFull chatFull = getChatFull(message.messageOwner.peer_id.channel_id);
|
||||
if (chatFull != null && (chatFull.call == null || chatFull.call != null && chatFull.call.id != message.messageOwner.action.call.id)) {
|
||||
if (chatFull != null && (chatFull.call == null || chatFull.call.id != message.messageOwner.action.call.id)) {
|
||||
loadFullChat(message.messageOwner.peer_id.channel_id, 0, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
package org.telegram.messenger;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.SystemClock;
|
||||
import android.text.SpannableStringBuilder;
|
||||
|
@ -87,7 +88,7 @@ public class MessagesStorage extends BaseController {
|
|||
private CountDownLatch openSync = new CountDownLatch(1);
|
||||
|
||||
private static volatile MessagesStorage[] Instance = new MessagesStorage[UserConfig.MAX_ACCOUNT_COUNT];
|
||||
private final static int LAST_DB_VERSION = 74;
|
||||
private final static int LAST_DB_VERSION = 76;
|
||||
|
||||
public static MessagesStorage getInstance(int num) {
|
||||
MessagesStorage localInstance = Instance[num];
|
||||
|
@ -332,7 +333,7 @@ public class MessagesStorage extends BaseController {
|
|||
database.executeFast("CREATE TABLE bot_keyboard(uid INTEGER PRIMARY KEY, mid INTEGER, info BLOB)").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid ON bot_keyboard(mid);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE chat_settings_v2(uid INTEGER PRIMARY KEY, info BLOB, pinned INTEGER, online INTEGER, inviter INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE chat_settings_v2(uid INTEGER PRIMARY KEY, info BLOB, pinned INTEGER, online INTEGER, inviter INTEGER, links INTEGER)").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS chat_settings_pinned_idx ON chat_settings_v2(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE user_settings(uid INTEGER PRIMARY KEY, info BLOB, pinned INTEGER)").stepThis().dispose();
|
||||
|
@ -371,6 +372,9 @@ public class MessagesStorage extends BaseController {
|
|||
database.executeFast("CREATE TABLE requested_holes(uid INTEGER, seq_out_start INTEGER, seq_out_end INTEGER, PRIMARY KEY (uid, seq_out_start, seq_out_end));").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE sharing_locations(uid INTEGER PRIMARY KEY, mid INTEGER, date INTEGER, period INTEGER, message BLOB, proximity INTEGER);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE shortcut_widget(id INTEGER, did INTEGER, ord INTEGER, PRIMARY KEY (id, did));").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS shortcut_widget_did ON shortcut_widget(did);").stepThis().dispose();
|
||||
|
||||
database.executeFast("CREATE TABLE emoji_keywords_v2(lang TEXT, keyword TEXT, emoji TEXT, PRIMARY KEY(lang, keyword, emoji));").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS emoji_keywords_v2_keyword ON emoji_keywords_v2(keyword);").stepThis().dispose();
|
||||
database.executeFast("CREATE TABLE emoji_keywords_info_v2(lang TEXT PRIMARY KEY, alias TEXT, version INTEGER, date INTEGER);").stepThis().dispose();
|
||||
|
@ -625,7 +629,7 @@ public class MessagesStorage extends BaseController {
|
|||
chatFull.id = chat_id;
|
||||
chatFull.chat_photo = new TLRPC.TL_photoEmpty();
|
||||
chatFull.notify_settings = new TLRPC.TL_peerNotifySettingsEmpty_layer77();
|
||||
chatFull.exported_invite = new TLRPC.TL_chatInviteEmpty();
|
||||
chatFull.exported_invite = null;
|
||||
chatFull.participants = participants;
|
||||
NativeByteBuffer data2 = new NativeByteBuffer(chatFull.getObjectSize());
|
||||
chatFull.serializeToStream(data2);
|
||||
|
@ -924,6 +928,17 @@ public class MessagesStorage extends BaseController {
|
|||
version = 74;
|
||||
}
|
||||
if (version == 74) {
|
||||
database.executeFast("CREATE TABLE IF NOT EXISTS shortcut_widget(id INTEGER, did INTEGER, ord INTEGER, PRIMARY KEY (id, did));").stepThis().dispose();
|
||||
database.executeFast("CREATE INDEX IF NOT EXISTS shortcut_widget_did ON shortcut_widget(did);").stepThis().dispose();
|
||||
database.executeFast("PRAGMA user_version = 75").stepThis().dispose();
|
||||
version = 75;
|
||||
}
|
||||
if (version == 75) {
|
||||
executeNoException("ALTER TABLE chat_settings_v2 ADD COLUMN links INTEGER default 0");
|
||||
database.executeFast("PRAGMA user_version = 76").stepThis().dispose();
|
||||
version = 76;
|
||||
}
|
||||
if (version == 76) {
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -3111,6 +3126,7 @@ public class MessagesStorage extends BaseController {
|
|||
}
|
||||
state5.dispose();
|
||||
state6.dispose();
|
||||
updateWidgets(did);
|
||||
}
|
||||
cursor.dispose();
|
||||
return;
|
||||
|
@ -3126,6 +3142,7 @@ public class MessagesStorage extends BaseController {
|
|||
getMediaDataController().clearBotKeyboard(did, null);
|
||||
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.needReloadRecentDialogsSearch));
|
||||
resetAllUnreadCounters(false);
|
||||
updateWidgets(did);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
|
@ -4506,6 +4523,7 @@ public class MessagesStorage extends BaseController {
|
|||
if (dialogsToUpdate.size() > 0 || dialogsToUpdateMentions.size() > 0) {
|
||||
database.beginTransaction();
|
||||
if (dialogsToUpdate.size() > 0) {
|
||||
ArrayList<Long> dids = new ArrayList<>();
|
||||
SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET unread_count = ? WHERE did = ?");
|
||||
for (int a = 0; a < dialogsToUpdate.size(); a++) {
|
||||
long did = dialogsToUpdate.keyAt(a);
|
||||
|
@ -4526,8 +4544,10 @@ public class MessagesStorage extends BaseController {
|
|||
state.bindInteger(1, newCount);
|
||||
state.bindLong(2, did);
|
||||
state.step();
|
||||
dids.add(did);
|
||||
}
|
||||
state.dispose();
|
||||
updateWidgets(dids);
|
||||
}
|
||||
if (dialogsToUpdateMentions.size() > 0) {
|
||||
SQLitePreparedStatement state = database.executeFast("UPDATE dialogs SET unread_count_i = ? WHERE did = ?");
|
||||
|
@ -4868,15 +4888,32 @@ public class MessagesStorage extends BaseController {
|
|||
});
|
||||
}
|
||||
|
||||
public void saveChatLinksCount(int chatId, int linksCount) {
|
||||
storageQueue.postRunnable(() -> {
|
||||
try {
|
||||
SQLitePreparedStatement state = database.executeFast("UPDATE chat_settings_v2 SET links = ? WHERE uid = ?");
|
||||
state.requery();
|
||||
state.bindInteger(1, linksCount);
|
||||
state.bindInteger(2, chatId);
|
||||
state.step();
|
||||
state.dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void updateChatInfo(final TLRPC.ChatFull info, final boolean ifExist) {
|
||||
storageQueue.postRunnable(() -> {
|
||||
try {
|
||||
int currentOnline = -1;
|
||||
int inviter = 0;
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT online, inviter FROM chat_settings_v2 WHERE uid = " + info.id);
|
||||
int links = 0;
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT online, inviter, links FROM chat_settings_v2 WHERE uid = " + info.id);
|
||||
if (cursor.next()) {
|
||||
currentOnline = cursor.intValue(0);
|
||||
info.inviterId = cursor.intValue(1);
|
||||
links = cursor.intValue(2);
|
||||
}
|
||||
cursor.dispose();
|
||||
if (ifExist && currentOnline == -1) {
|
||||
|
@ -4887,7 +4924,11 @@ public class MessagesStorage extends BaseController {
|
|||
info.online_count = currentOnline;
|
||||
}
|
||||
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_settings_v2 VALUES(?, ?, ?, ?, ?)");
|
||||
if (links >= 0) {
|
||||
info.invitesCount = links;
|
||||
}
|
||||
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_settings_v2 VALUES(?, ?, ?, ?, ?, ?)");
|
||||
NativeByteBuffer data = new NativeByteBuffer(info.getObjectSize());
|
||||
info.serializeToStream(data);
|
||||
state.bindInteger(1, info.id);
|
||||
|
@ -4895,6 +4936,7 @@ public class MessagesStorage extends BaseController {
|
|||
state.bindInteger(3, info.pinned_msg_id);
|
||||
state.bindInteger(4, info.online_count);
|
||||
state.bindInteger(5, info.inviterId);
|
||||
state.bindInteger(6, info.invitesCount);
|
||||
state.step();
|
||||
state.dispose();
|
||||
data.reuse();
|
||||
|
@ -5231,7 +5273,7 @@ public class MessagesStorage extends BaseController {
|
|||
boolean pinnedEndReached = false;
|
||||
|
||||
try {
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned, online, inviter FROM chat_settings_v2 WHERE uid = " + chatId);
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned, online, inviter, links FROM chat_settings_v2 WHERE uid = " + chatId);
|
||||
if (cursor.next()) {
|
||||
NativeByteBuffer data = cursor.byteBufferValue(0);
|
||||
if (data != null) {
|
||||
|
@ -5240,6 +5282,7 @@ public class MessagesStorage extends BaseController {
|
|||
info.pinned_msg_id = cursor.intValue(1);
|
||||
info.online_count = cursor.intValue(2);
|
||||
info.inviterId = cursor.intValue(3);
|
||||
info.invitesCount = cursor.intValue(4);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
|
@ -5465,6 +5508,7 @@ public class MessagesStorage extends BaseController {
|
|||
dialogsToUpdate.put(dialog_id, unreadCount);
|
||||
updateFiltersReadCounter(dialogsToUpdate, null, true);
|
||||
}
|
||||
updateWidgets(dialog_id);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
|
@ -6110,7 +6154,7 @@ public class MessagesStorage extends BaseController {
|
|||
if (load_type == 3 && minDate == 0) {
|
||||
cursor = database.queryFinalized("SELECT inbox_max, unread_count, date, unread_count_i FROM dialogs WHERE did = " + dialogId);
|
||||
if (cursor.next()) {
|
||||
min_unread_id = cursor.intValue(0) + 1;
|
||||
min_unread_id = Math.max(1, cursor.intValue(0)) + 1;
|
||||
count_unread = cursor.intValue(1);
|
||||
max_unread_date = cursor.intValue(2);
|
||||
mentions_unread = cursor.intValue(3);
|
||||
|
@ -6120,7 +6164,7 @@ public class MessagesStorage extends BaseController {
|
|||
if (load_type == 2) {
|
||||
cursor = database.queryFinalized("SELECT inbox_max, unread_count, date, unread_count_i FROM dialogs WHERE did = " + dialogId);
|
||||
if (cursor.next()) {
|
||||
messageMaxId = max_id_query = min_unread_id = cursor.intValue(0);
|
||||
messageMaxId = max_id_query = min_unread_id = Math.max(1, cursor.intValue(0));
|
||||
count_unread = cursor.intValue(1);
|
||||
max_unread_date = cursor.intValue(2);
|
||||
mentions_unread = cursor.intValue(3);
|
||||
|
@ -6793,6 +6837,122 @@ public class MessagesStorage extends BaseController {
|
|||
return result[0] != null ? result : null;
|
||||
}
|
||||
|
||||
private void updateWidgets(long did) {
|
||||
ArrayList<Long> dids = new ArrayList<>();
|
||||
dids.add(did);
|
||||
updateWidgets(dids);
|
||||
}
|
||||
|
||||
private void updateWidgets(ArrayList<Long> dids) {
|
||||
try {
|
||||
AppWidgetManager appWidgetManager = null;
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT DISTINCT id FROM shortcut_widget WHERE did IN(%s)", TextUtils.join(",", dids)));
|
||||
while (cursor.next()) {
|
||||
if (appWidgetManager == null) {
|
||||
appWidgetManager = AppWidgetManager.getInstance(ApplicationLoader.applicationContext);
|
||||
}
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(cursor.intValue(0), R.id.list_view);
|
||||
}
|
||||
cursor.dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void putWidgetDialogs(int widgetId, ArrayList<Long> dids) {
|
||||
storageQueue.postRunnable(() -> {
|
||||
try {
|
||||
SQLitePreparedStatement state = database.executeFast("REPLACE INTO shortcut_widget VALUES(?, ?, ?)");
|
||||
for (int a = 0, N = dids.size(); a < N; a++) {
|
||||
long did = dids.get(a);
|
||||
state.requery();
|
||||
state.bindInteger(1, widgetId);
|
||||
state.bindInteger(2, (int) did);
|
||||
state.bindInteger(3, a);
|
||||
state.step();
|
||||
}
|
||||
state.dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void clearWidgetDialogs(int widgetId) {
|
||||
storageQueue.postRunnable(() -> {
|
||||
try {
|
||||
database.executeFast("DELETE FROM shortcut_widget WHERE id = " + widgetId).stepThis().dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void getWidgetDialogs(int widgetId, ArrayList<Integer> dids, LongSparseArray<TLRPC.Dialog> dialogs, LongSparseArray<TLRPC.Message> messages, ArrayList<TLRPC.User> users, ArrayList<TLRPC.Chat> chats) {
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
storageQueue.postRunnable(() -> {
|
||||
try {
|
||||
ArrayList<Integer> usersToLoad = new ArrayList<>();
|
||||
ArrayList<Integer> chatsToLoad = new ArrayList<>();
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT did FROM shortcut_widget WHERE id = %d ORDER BY ord ASC", widgetId));
|
||||
while (cursor.next()) {
|
||||
int id = cursor.intValue(0);
|
||||
dids.add(id);
|
||||
if (id > 0) {
|
||||
usersToLoad.add(id);
|
||||
} else {
|
||||
chatsToLoad.add(-id);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, m.date FROM dialogs as d LEFT JOIN messages as m ON d.last_mid = m.mid WHERE d.did IN(%s)", TextUtils.join(",", dids)));
|
||||
while (cursor.next()) {
|
||||
long dialogId = cursor.longValue(0);
|
||||
TLRPC.Dialog dialog = new TLRPC.TL_dialog();
|
||||
dialog.id = dialogId;
|
||||
dialog.top_message = cursor.intValue(1);
|
||||
dialog.unread_count = cursor.intValue(2);
|
||||
dialog.last_message_date = cursor.intValue(3);
|
||||
|
||||
dialogs.put(dialog.id, dialog);
|
||||
|
||||
NativeByteBuffer data = cursor.byteBufferValue(4);
|
||||
if (data != null) {
|
||||
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
|
||||
message.readAttachPath(data, getUserConfig().clientUserId);
|
||||
data.reuse();
|
||||
MessageObject.setUnreadFlags(message, cursor.intValue(5));
|
||||
message.id = cursor.intValue(6);
|
||||
message.send_state = cursor.intValue(7);
|
||||
int date = cursor.intValue(8);
|
||||
if (date != 0) {
|
||||
dialog.last_message_date = date;
|
||||
}
|
||||
message.dialog_id = dialog.id;
|
||||
messages.put(dialog.id, message);
|
||||
addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
if (!chatsToLoad.isEmpty()) {
|
||||
getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
|
||||
}
|
||||
if (!usersToLoad.isEmpty()) {
|
||||
getUsersInternal(TextUtils.join(",", usersToLoad), users);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
} finally {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
});
|
||||
try {
|
||||
countDownLatch.await();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void putSentFile(final String path, final TLObject file, final int type, String parent) {
|
||||
if (path == null || file == null || parent == null) {
|
||||
return;
|
||||
|
@ -7158,12 +7318,14 @@ public class MessagesStorage extends BaseController {
|
|||
oldUser.username = null;
|
||||
oldUser.flags = oldUser.flags & ~8;
|
||||
}
|
||||
if (user.photo != null) {
|
||||
oldUser.photo = user.photo;
|
||||
oldUser.flags |= 32;
|
||||
} else {
|
||||
oldUser.photo = null;
|
||||
oldUser.flags = oldUser.flags & ~32;
|
||||
if (user.apply_min_photo) {
|
||||
if (user.photo != null) {
|
||||
oldUser.photo = user.photo;
|
||||
oldUser.flags |= 32;
|
||||
} else {
|
||||
oldUser.photo = null;
|
||||
oldUser.flags = oldUser.flags & ~32;
|
||||
}
|
||||
}
|
||||
user = oldUser;
|
||||
}
|
||||
|
@ -8338,6 +8500,7 @@ public class MessagesStorage extends BaseController {
|
|||
SQLitePreparedStatement state_dialogs_replace = database.executeFast("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
SQLitePreparedStatement state_dialogs_update = database.executeFast("UPDATE dialogs SET date = ?, unread_count = ?, last_mid = ?, unread_count_i = ? WHERE did = ?");
|
||||
|
||||
ArrayList<Long> dids = new ArrayList<>();
|
||||
for (int a = 0; a < messagesMap.size(); a++) {
|
||||
long key = messagesMap.keyAt(a);
|
||||
if (key == 0) {
|
||||
|
@ -8395,6 +8558,7 @@ public class MessagesStorage extends BaseController {
|
|||
newMentionsCounts.put(key, mentions_count);
|
||||
}
|
||||
|
||||
dids.add(key);
|
||||
if (exists) {
|
||||
state_dialogs_update.requery();
|
||||
state_dialogs_update.bindInteger(1, message != null && (!doNotUpdateDialogDate || dialog_date == 0) ? message.date : dialog_date);
|
||||
|
@ -8465,6 +8629,7 @@ public class MessagesStorage extends BaseController {
|
|||
final int downloadMediaMaskFinal = downloadMediaMask;
|
||||
AndroidUtilities.runOnUIThread(() -> getDownloadController().newDownloadObjectsAvailable(downloadMediaMaskFinal));
|
||||
}
|
||||
updateWidgets(dids);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
|
@ -9164,6 +9329,7 @@ public class MessagesStorage extends BaseController {
|
|||
if (dialogsToUpdate.size() != 0) {
|
||||
resetAllUnreadCounters(false);
|
||||
}
|
||||
updateWidgets(dialogsIds);
|
||||
}
|
||||
return dialogsIds;
|
||||
} catch (Exception e) {
|
||||
|
@ -9440,6 +9606,7 @@ public class MessagesStorage extends BaseController {
|
|||
database.executeFast(String.format(Locale.US, "DELETE FROM messages WHERE uid = %d AND mid <= %d", -channelId, maxMessageId)).stepThis().dispose();
|
||||
database.executeFast(String.format(Locale.US, "DELETE FROM media_v2 WHERE uid = %d AND mid <= %d", -channelId, maxMessageId)).stepThis().dispose();
|
||||
database.executeFast(String.format(Locale.US, "UPDATE media_counts_v2 SET old = 1 WHERE uid = %d", -channelId)).stepThis().dispose();
|
||||
updateWidgets(dialogsIds);
|
||||
return dialogsIds;
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
|
@ -10790,11 +10957,27 @@ public class MessagesStorage extends BaseController {
|
|||
private void checkIfFolderEmptyInternal(int folderId) {
|
||||
try {
|
||||
SQLiteCursor cursor = database.queryFinalized("SELECT did FROM dialogs WHERE folder_id = ?", folderId);
|
||||
if (!cursor.next()) {
|
||||
boolean isEmpty = true;
|
||||
while (cursor.next()) {
|
||||
long did = cursor.longValue(0);
|
||||
int lowerId = (int) did;
|
||||
int highId = (int) (did >> 32);
|
||||
if (lowerId > 0 || highId != 0 && lowerId == 0) {
|
||||
isEmpty = false;
|
||||
break;
|
||||
} else {
|
||||
TLRPC.Chat chat = getChat(-lowerId);
|
||||
if (!ChatObject.isNotInChat(chat) && chat.migrated_to == null) {
|
||||
isEmpty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cursor.dispose();
|
||||
if (isEmpty) {
|
||||
AndroidUtilities.runOnUIThread(() -> getMessagesController().onFolderEmpty(folderId));
|
||||
database.executeFast("DELETE FROM dialogs WHERE did = " + DialogObject.makeFolderDialogId(folderId)).stepThis().dispose();
|
||||
}
|
||||
cursor.dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
|
|
|
@ -113,6 +113,8 @@ public class NotificationCenter {
|
|||
public static final int newSuggestionsAvailable = totalEvents++;
|
||||
public static final int didLoadChatInviter = totalEvents++;
|
||||
public static final int didLoadChatAdmins = totalEvents++;
|
||||
public static final int historyImportProgressChanged = totalEvents++;
|
||||
public static final int dialogDeleted = totalEvents++;
|
||||
|
||||
public static final int walletPendingTransactionsChanged = totalEvents++;
|
||||
public static final int walletSyncProgressChanged = totalEvents++;
|
||||
|
@ -152,6 +154,7 @@ public class NotificationCenter {
|
|||
|
||||
public static final int didStartedCall = totalEvents++;
|
||||
public static final int groupCallUpdated = totalEvents++;
|
||||
public static final int applyGroupCallVisibleParticipants = totalEvents++;
|
||||
public static final int groupCallTypingsUpdated = totalEvents++;
|
||||
public static final int didEndCall = totalEvents++;
|
||||
public static final int closeInCallActivity = totalEvents++;
|
||||
|
|
|
@ -594,8 +594,6 @@ public class NotificationsController extends BaseController {
|
|||
if (lower_id != 0) {
|
||||
if (preferences.getBoolean("custom_" + dialog_id, false)) {
|
||||
popup = preferences.getInt("popup_" + dialog_id, 0);
|
||||
} else {
|
||||
popup = 0;
|
||||
}
|
||||
if (popup == 0) {
|
||||
if (isChannel) {
|
||||
|
@ -2082,7 +2080,7 @@ public class NotificationsController extends BaseController {
|
|||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionScreenshotTaken) {
|
||||
msg = messageObject.messageText.toString();
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage) {
|
||||
if (chat != null && (!ChatObject.isChannel(chat) || chat.megagroup)) {
|
||||
if (!ChatObject.isChannel(chat) || chat.megagroup) {
|
||||
if (messageObject.replyMessageObject == null) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedNoText", R.string.NotificationActionPinnedNoText, name, chat.title);
|
||||
} else {
|
||||
|
@ -2154,7 +2152,7 @@ public class NotificationsController extends BaseController {
|
|||
msg = LocaleController.formatString("NotificationActionPinnedNoText", R.string.NotificationActionPinnedNoText, name, chat.title);
|
||||
}
|
||||
}
|
||||
} else if (chat != null) {
|
||||
} else {
|
||||
if (messageObject.replyMessageObject == null) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedNoTextChannel", R.string.NotificationActionPinnedNoTextChannel, chat.title);
|
||||
} else {
|
||||
|
@ -2226,78 +2224,6 @@ public class NotificationsController extends BaseController {
|
|||
msg = LocaleController.formatString("NotificationActionPinnedNoTextChannel", R.string.NotificationActionPinnedNoTextChannel, chat.title);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (messageObject.replyMessageObject == null) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedNoTextUser", R.string.NotificationActionPinnedNoTextUser, name);
|
||||
} else {
|
||||
MessageObject object = messageObject.replyMessageObject;
|
||||
if (object.isMusic()) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedMusicUser", R.string.NotificationActionPinnedMusicUser, name);
|
||||
} else if (object.isVideo()) {
|
||||
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
|
||||
String message = "\uD83D\uDCF9 " + object.messageOwner.message;
|
||||
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedVideoUser", R.string.NotificationActionPinnedVideoUser, name);
|
||||
}
|
||||
} else if (object.isGif()) {
|
||||
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
|
||||
String message = "\uD83C\uDFAC " + object.messageOwner.message;
|
||||
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedGifUser", R.string.NotificationActionPinnedGifUser, name);
|
||||
}
|
||||
} else if (object.isVoice()) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedVoiceUser", R.string.NotificationActionPinnedVoiceUser, name);
|
||||
} else if (object.isRoundVideo()) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedRoundUser", R.string.NotificationActionPinnedRoundUser, name);
|
||||
} else if (object.isSticker() || object.isAnimatedSticker()) {
|
||||
String emoji = object.getStickerEmoji();
|
||||
if (emoji != null) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedStickerEmojiUser", R.string.NotificationActionPinnedStickerEmojiUser, name, emoji);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedStickerUser", R.string.NotificationActionPinnedStickerUser, name);
|
||||
}
|
||||
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
|
||||
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
|
||||
String message = "\uD83D\uDCCE " + object.messageOwner.message;
|
||||
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedFileUser", R.string.NotificationActionPinnedFileUser, name);
|
||||
}
|
||||
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || object.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedGeoUser", R.string.NotificationActionPinnedGeoUser, name);
|
||||
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedGeoLiveUser", R.string.NotificationActionPinnedGeoLiveUser, name);
|
||||
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaContact) {
|
||||
TLRPC.TL_messageMediaContact mediaContact = (TLRPC.TL_messageMediaContact) messageObject.messageOwner.media;
|
||||
msg = LocaleController.formatString("NotificationActionPinnedContactUser", R.string.NotificationActionPinnedContactUser, name, ContactsController.formatName(mediaContact.first_name, mediaContact.last_name));
|
||||
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
|
||||
TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) object.messageOwner.media;
|
||||
if (mediaPoll.poll.quiz) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedQuizUser", R.string.NotificationActionPinnedQuizUser, name, mediaPoll.poll.question);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedPollUser", R.string.NotificationActionPinnedPollUser, name, mediaPoll.poll.question);
|
||||
}
|
||||
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
|
||||
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(object.messageOwner.message)) {
|
||||
String message = "\uD83D\uDDBC " + object.messageOwner.message;
|
||||
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedPhotoUser", R.string.NotificationActionPinnedPhotoUser, name);
|
||||
}
|
||||
} else if (object.messageOwner.media instanceof TLRPC.TL_messageMediaGame) {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedGameUser", R.string.NotificationActionPinnedGameUser, name);
|
||||
} else if (object.messageText != null && object.messageText.length() > 0) {
|
||||
CharSequence message = object.messageText;
|
||||
if (message.length() > 20) {
|
||||
message = message.subSequence(0, 20) + "...";
|
||||
}
|
||||
msg = LocaleController.formatString("NotificationActionPinnedTextUser", R.string.NotificationActionPinnedTextUser, name, message);
|
||||
} else {
|
||||
msg = LocaleController.formatString("NotificationActionPinnedNoTextUser", R.string.NotificationActionPinnedNoTextUser, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGameScore) {
|
||||
msg = messageObject.messageText.toString();
|
||||
|
@ -2637,85 +2563,95 @@ public class NotificationsController extends BaseController {
|
|||
deleteNotificationChannel(dialogId, -1);
|
||||
}
|
||||
|
||||
private void deleteNotificationChannelInternal(long dialogId, int what) {
|
||||
if (Build.VERSION.SDK_INT < 26) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
if (what == 0 || what == -1) {
|
||||
String key = "org.telegram.key" + dialogId;
|
||||
String channelId = preferences.getString(key, null);
|
||||
if (channelId != null) {
|
||||
editor.remove(key).remove(key + "_s");
|
||||
systemNotificationManager.deleteNotificationChannel(channelId);
|
||||
}
|
||||
}
|
||||
if (what == 1 || what == -1) {
|
||||
String key = "org.telegram.keyia" + dialogId;
|
||||
String channelId = preferences.getString(key, null);
|
||||
if (channelId != null) {
|
||||
editor.remove(key).remove(key + "_s");
|
||||
systemNotificationManager.deleteNotificationChannel(channelId);
|
||||
}
|
||||
}
|
||||
editor.commit();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteNotificationChannel(long dialogId, int what) {
|
||||
if (Build.VERSION.SDK_INT < 26) {
|
||||
return;
|
||||
}
|
||||
notificationsQueue.postRunnable(() -> {
|
||||
try {
|
||||
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
if (what == 0 || what == -1) {
|
||||
String key = "org.telegram.key" + dialogId;
|
||||
String channelId = preferences.getString(key, null);
|
||||
if (channelId != null) {
|
||||
editor.remove(key).remove(key + "_s");
|
||||
systemNotificationManager.deleteNotificationChannel(channelId);
|
||||
}
|
||||
}
|
||||
if (what == 1 || what == -1) {
|
||||
String key = "org.telegram.keyia" + dialogId;
|
||||
String channelId = preferences.getString(key, null);
|
||||
if (channelId != null) {
|
||||
editor.remove(key).remove(key + "_s");
|
||||
systemNotificationManager.deleteNotificationChannel(channelId);
|
||||
}
|
||||
}
|
||||
editor.commit();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
notificationsQueue.postRunnable(() -> deleteNotificationChannelInternal(dialogId, what));
|
||||
}
|
||||
|
||||
public void deleteNotificationChannelGlobal(int type) {
|
||||
deleteNotificationChannelGlobal(type, -1);
|
||||
}
|
||||
|
||||
public void deleteNotificationChannelGlobalInternal(int type, int what) {
|
||||
if (Build.VERSION.SDK_INT < 26) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
if (what == 0 || what == -1) {
|
||||
String key;
|
||||
if (type == TYPE_CHANNEL) {
|
||||
key = "channels";
|
||||
} else if (type == TYPE_GROUP) {
|
||||
key = "groups";
|
||||
} else {
|
||||
key = "private";
|
||||
}
|
||||
String channelId = preferences.getString(key, null);
|
||||
if (channelId != null) {
|
||||
editor.remove(key).remove(key + "_s");
|
||||
systemNotificationManager.deleteNotificationChannel(channelId);
|
||||
}
|
||||
}
|
||||
|
||||
if (what == 1 || what == -1) {
|
||||
String key;
|
||||
if (type == TYPE_CHANNEL) {
|
||||
key = "channels_ia";
|
||||
} else if (type == TYPE_GROUP) {
|
||||
key = "groups_ia";
|
||||
} else {
|
||||
key = "private_ia";
|
||||
}
|
||||
String channelId = preferences.getString(key, null);
|
||||
if (channelId != null) {
|
||||
editor.remove(key).remove(key + "_s");
|
||||
systemNotificationManager.deleteNotificationChannel(channelId);
|
||||
}
|
||||
}
|
||||
editor.commit();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteNotificationChannelGlobal(int type, int what) {
|
||||
if (Build.VERSION.SDK_INT < 26) {
|
||||
return;
|
||||
}
|
||||
notificationsQueue.postRunnable(() -> {
|
||||
try {
|
||||
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
if (what == 0 || what == -1) {
|
||||
String key;
|
||||
if (type == TYPE_CHANNEL) {
|
||||
key = "channels";
|
||||
} else if (type == TYPE_GROUP) {
|
||||
key = "groups";
|
||||
} else {
|
||||
key = "private";
|
||||
}
|
||||
String channelId = preferences.getString(key, null);
|
||||
if (channelId != null) {
|
||||
editor.remove(key).remove(key + "_s");
|
||||
systemNotificationManager.deleteNotificationChannel(channelId);
|
||||
}
|
||||
}
|
||||
|
||||
if (what == 1 || what == -1) {
|
||||
String key;
|
||||
if (type == TYPE_CHANNEL) {
|
||||
key = "channels_ia";
|
||||
} else if (type == TYPE_GROUP) {
|
||||
key = "groups_ia";
|
||||
} else {
|
||||
key = "private_ia";
|
||||
}
|
||||
String channelId = preferences.getString(key, null);
|
||||
if (channelId != null) {
|
||||
editor.remove(key).remove(key + "_s");
|
||||
systemNotificationManager.deleteNotificationChannel(channelId);
|
||||
}
|
||||
}
|
||||
editor.commit();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
notificationsQueue.postRunnable(() -> deleteNotificationChannelGlobalInternal(type, what));
|
||||
}
|
||||
|
||||
public void deleteAllNotificationChannels() {
|
||||
|
@ -2748,9 +2684,9 @@ public class NotificationsController extends BaseController {
|
|||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
private void createNotificationShortcut(NotificationCompat.Builder builder, int did, String name, TLRPC.User user, TLRPC.Chat chat, Person person) {
|
||||
private String createNotificationShortcut(NotificationCompat.Builder builder, int did, String name, TLRPC.User user, TLRPC.Chat chat, Person person) {
|
||||
if (unsupportedNotificationShortcut() || ChatObject.isChannel(chat) && !chat.megagroup) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
String id = "ndid_" + did;
|
||||
|
@ -2782,7 +2718,7 @@ public class NotificationsController extends BaseController {
|
|||
}
|
||||
intent.putExtra("currentAccount", currentAccount);
|
||||
bubbleBuilder.setIntent(PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
|
||||
bubbleBuilder.setSuppressNotification(true);
|
||||
bubbleBuilder.setSuppressNotification(opened_dialog_id == did);
|
||||
bubbleBuilder.setAutoExpandBubble(false);
|
||||
bubbleBuilder.setDesiredHeight(AndroidUtilities.dp(640));
|
||||
if (avatar != null) {
|
||||
|
@ -2795,9 +2731,11 @@ public class NotificationsController extends BaseController {
|
|||
}
|
||||
}
|
||||
builder.setBubbleMetadata(bubbleBuilder.build());
|
||||
return id;
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@TargetApi(26)
|
||||
|
@ -3650,10 +3588,7 @@ public class NotificationsController extends BaseController {
|
|||
mBuilder.addAction(R.drawable.ic_ab_reply, LocaleController.getString("Reply", R.string.Reply), PendingIntent.getBroadcast(ApplicationLoader.applicationContext, 2, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT));
|
||||
}
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
mBuilder.setChannelId(validateChannelId(dialog_id, chatName, vibrationPattern, ledColor, sound, configImportance, isDefault, isInApp, notifyDisabled, chatType));
|
||||
}
|
||||
showExtraNotifications(mBuilder, detailText);
|
||||
showExtraNotifications(mBuilder, detailText, dialog_id, chatName, vibrationPattern, ledColor, sound, configImportance, isDefault, isInApp, notifyDisabled, chatType);
|
||||
scheduleNotificationRepeat();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
|
@ -3669,8 +3604,47 @@ public class NotificationsController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
private void resetNotificationSound(NotificationCompat.Builder notificationBuilder, long dialogId, String chatName, long[] vibrationPattern, int ledColor, Uri sound, int importance, boolean isDefault, boolean isInApp, boolean isSilent, int chatType) {
|
||||
Uri defaultSound = Settings.System.DEFAULT_RINGTONE_URI;
|
||||
if (defaultSound != null && sound != null && !TextUtils.equals(defaultSound.toString(), sound.toString())) {
|
||||
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
|
||||
String newSound = defaultSound.toString();
|
||||
String ringtoneName = LocaleController.getString("DefaultRingtone", R.string.DefaultRingtone);
|
||||
if (isDefault) {
|
||||
if (chatType == TYPE_CHANNEL) {
|
||||
editor.putString("ChannelSound", ringtoneName);
|
||||
} else if (chatType == TYPE_GROUP) {
|
||||
editor.putString("GroupSound", ringtoneName);
|
||||
} else {
|
||||
editor.putString("GlobalSound", ringtoneName);
|
||||
}
|
||||
if (chatType == TYPE_CHANNEL) {
|
||||
editor.putString("ChannelSoundPath", newSound);
|
||||
} else if (chatType == TYPE_GROUP) {
|
||||
editor.putString("GroupSoundPath", newSound);
|
||||
} else {
|
||||
editor.putString("GlobalSoundPath", newSound);
|
||||
}
|
||||
getNotificationsController().deleteNotificationChannelGlobalInternal(chatType, -1);
|
||||
} else {
|
||||
editor.putString("sound_" + dialogId, ringtoneName);
|
||||
editor.putString("sound_path_" + dialogId, newSound);
|
||||
deleteNotificationChannelInternal(dialogId, -1);
|
||||
}
|
||||
editor.commit();
|
||||
sound = Settings.System.DEFAULT_RINGTONE_URI;
|
||||
notificationBuilder.setChannelId(validateChannelId(dialogId, chatName, vibrationPattern, ledColor, sound, importance, isDefault, isInApp, isSilent, chatType));
|
||||
notificationManager.notify(notificationId, notificationBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
private void showExtraNotifications(NotificationCompat.Builder notificationBuilder, String summary) {
|
||||
private void showExtraNotifications(NotificationCompat.Builder notificationBuilder, String summary, long dialogId, String chatName, long[] vibrationPattern, int ledColor, Uri sound, int importance, boolean isDefault, boolean isInApp, boolean isSilent, int chatType) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
notificationBuilder.setChannelId(validateChannelId(dialogId, chatName, vibrationPattern, ledColor, sound, importance, isDefault, isInApp, isSilent, chatType));
|
||||
}
|
||||
Notification mainNotification = notificationBuilder.build();
|
||||
if (Build.VERSION.SDK_INT < 18) {
|
||||
notificationManager.notify(notificationId, mainNotification);
|
||||
|
@ -3696,7 +3670,7 @@ public class NotificationsController extends BaseController {
|
|||
if (arrayList == null) {
|
||||
arrayList = new ArrayList<>();
|
||||
messagesByDialogs.put(dialog_id, arrayList);
|
||||
sortedDialogs.add(0, dialog_id);
|
||||
sortedDialogs.add(dialog_id);
|
||||
}
|
||||
arrayList.add(messageObject);
|
||||
}
|
||||
|
@ -3706,18 +3680,31 @@ public class NotificationsController extends BaseController {
|
|||
|
||||
class NotificationHolder {
|
||||
int id;
|
||||
Notification notification;
|
||||
int lowerId;
|
||||
String name;
|
||||
TLRPC.User user;
|
||||
TLRPC.Chat chat;
|
||||
NotificationCompat.Builder notification;
|
||||
|
||||
NotificationHolder(int i, Notification n) {
|
||||
NotificationHolder(int i, int li, String n, TLRPC.User u, TLRPC.Chat c, NotificationCompat.Builder builder) {
|
||||
id = i;
|
||||
notification = n;
|
||||
name = n;
|
||||
user = u;
|
||||
chat = c;
|
||||
notification = builder;
|
||||
lowerId = li;
|
||||
}
|
||||
|
||||
void call() {
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.w("show dialog notification with id " + id);
|
||||
}
|
||||
notificationManager.notify(id, notification);
|
||||
try {
|
||||
notificationManager.notify(id, notification.build());
|
||||
} catch (SecurityException e) {
|
||||
FileLog.e(e);
|
||||
resetNotificationSound(notification, dialogId, chatName, vibrationPattern, ledColor, sound, importance, isDefault, isInApp, isSilent, chatType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3727,7 +3714,7 @@ public class NotificationsController extends BaseController {
|
|||
serializedNotifications = new JSONArray();
|
||||
}
|
||||
|
||||
boolean useSummaryNotification = Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1 || Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1 && sortedDialogs.size() > 1;
|
||||
boolean useSummaryNotification = Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1 || sortedDialogs.size() > 1;
|
||||
if (useSummaryNotification && Build.VERSION.SDK_INT >= 26) {
|
||||
checkOtherNotificationsChannel();
|
||||
}
|
||||
|
@ -3735,12 +3722,8 @@ public class NotificationsController extends BaseController {
|
|||
int selfUserId = getUserConfig().getClientUserId();
|
||||
boolean waitingForPasscode = AndroidUtilities.needShowPasscode() || SharedConfig.isWaitingForPasscodeEnter;
|
||||
|
||||
int maxCount;
|
||||
if (UserConfig.getActivatedAccountsCount() >= 3) {
|
||||
maxCount = 7;
|
||||
} else {
|
||||
maxCount = 10;
|
||||
}
|
||||
int maxCount = 7;
|
||||
LongSparseArray<Person> personCache = new LongSparseArray<>();
|
||||
for (int b = 0, size = sortedDialogs.size(); b < size; b++) {
|
||||
if (holders.size() >= maxCount) {
|
||||
break;
|
||||
|
@ -3782,7 +3765,6 @@ public class NotificationsController extends BaseController {
|
|||
Bitmap avatarBitmap = null;
|
||||
File avatalFile = null;
|
||||
boolean canReply;
|
||||
LongSparseArray<Person> personCache = new LongSparseArray<>();
|
||||
|
||||
if (lowerId != 0) {
|
||||
canReply = lowerId != 777000;
|
||||
|
@ -4021,7 +4003,7 @@ public class NotificationsController extends BaseController {
|
|||
File avatar = null;
|
||||
if (lowerId > 0 || isChannel) {
|
||||
avatar = avatalFile;
|
||||
} else if (lowerId < 0) {
|
||||
} else {
|
||||
int fromId = messageObject.getSenderId();
|
||||
TLRPC.User sender = getMessagesController().getUser(fromId);
|
||||
if (sender == null) {
|
||||
|
@ -4199,7 +4181,7 @@ public class NotificationsController extends BaseController {
|
|||
.setStyle(messagingStyle)
|
||||
.setContentIntent(contentIntent)
|
||||
.extend(wearableExtender)
|
||||
.setSortKey("" + (Long.MAX_VALUE - date))
|
||||
.setSortKey(String.valueOf(Long.MAX_VALUE - date))
|
||||
.setCategory(NotificationCompat.CATEGORY_MESSAGE);
|
||||
|
||||
Intent dismissIntent = new Intent(ApplicationLoader.applicationContext, NotificationDismissReceiver.class);
|
||||
|
@ -4248,11 +4230,6 @@ public class NotificationsController extends BaseController {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
if (lowerId != 0) {
|
||||
createNotificationShortcut(builder, lowerId, name, user, chat, personCache.get(lowerId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chat == null && user != null && user.phone != null && user.phone.length() > 0) {
|
||||
|
@ -4262,7 +4239,7 @@ public class NotificationsController extends BaseController {
|
|||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
setNotificationChannel(mainNotification, builder, useSummaryNotification);
|
||||
}
|
||||
holders.add(new NotificationHolder(internalId, builder.build()));
|
||||
holders.add(new NotificationHolder(internalId, lowerId, name, user, chat, builder));
|
||||
wearNotificationsIds.put(dialog_id, internalId);
|
||||
|
||||
if (lowerId != 0) {
|
||||
|
@ -4281,7 +4258,7 @@ public class NotificationsController extends BaseController {
|
|||
}
|
||||
if (lowerId > 0) {
|
||||
serializedChat.put("type", "user");
|
||||
} else if (lowerId < 0) {
|
||||
} else {
|
||||
if (isChannel || isSupergroup) {
|
||||
serializedChat.put("type", "channel");
|
||||
} else {
|
||||
|
@ -4299,27 +4276,17 @@ public class NotificationsController extends BaseController {
|
|||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("show summary with id " + notificationId);
|
||||
}
|
||||
notificationManager.notify(notificationId, mainNotification);
|
||||
try {
|
||||
notificationManager.notify(notificationId, mainNotification);
|
||||
} catch (SecurityException e) {
|
||||
FileLog.e(e);
|
||||
resetNotificationSound(notificationBuilder, dialogId, chatName, vibrationPattern, ledColor, sound, importance, isDefault, isInApp, isSilent, chatType);
|
||||
}
|
||||
} else {
|
||||
if (openedInBubbleDialogs.isEmpty()) {
|
||||
notificationManager.cancel(notificationId);
|
||||
}
|
||||
}
|
||||
ArrayList<String> ids = new ArrayList<>(holders.size());
|
||||
for (int a = 0, size = holders.size(); a < size; a++) {
|
||||
NotificationHolder holder = holders.get(a);
|
||||
holder.call();
|
||||
if (!unsupportedNotificationShortcut()) {
|
||||
ids.add(holder.notification.getShortcutId());
|
||||
}
|
||||
}
|
||||
if (!unsupportedNotificationShortcut()) {
|
||||
try {
|
||||
ShortcutManagerCompat.removeDynamicShortcuts(ApplicationLoader.applicationContext, ids);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a < oldIdsWear.size(); a++) {
|
||||
long did = oldIdsWear.keyAt(a);
|
||||
|
@ -4332,6 +4299,23 @@ public class NotificationsController extends BaseController {
|
|||
}
|
||||
notificationManager.cancel(id);
|
||||
}
|
||||
|
||||
ArrayList<String> ids = new ArrayList<>(holders.size());
|
||||
for (int a = 0, size = holders.size(); a < size; a++) {
|
||||
NotificationHolder holder = holders.get(a);
|
||||
ids.clear();
|
||||
if (Build.VERSION.SDK_INT >= 29 && holder.lowerId != 0) {
|
||||
String shortcutId = createNotificationShortcut(holder.notification, holder.lowerId, holder.name, holder.user, holder.chat, personCache.get(holder.lowerId));
|
||||
if (shortcutId != null) {
|
||||
ids.add(shortcutId);
|
||||
}
|
||||
}
|
||||
holder.call();
|
||||
if (!unsupportedNotificationShortcut() && !ids.isEmpty()) {
|
||||
ShortcutManagerCompat.removeDynamicShortcuts(ApplicationLoader.applicationContext, ids);
|
||||
}
|
||||
}
|
||||
|
||||
if (serializedNotifications != null) {
|
||||
try {
|
||||
JSONObject s = new JSONObject();
|
||||
|
|
|
@ -244,6 +244,9 @@ public class SecretChatHelper extends BaseController {
|
|||
getNotificationCenter().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat);
|
||||
});
|
||||
}
|
||||
if (newChat instanceof TLRPC.TL_encryptedChatDiscarded && newChat.history_deleted) {
|
||||
AndroidUtilities.runOnUIThread(() -> getMessagesController().deleteDialog(dialog_id, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessagesDeleteMessage(TLRPC.EncryptedChat encryptedChat, ArrayList<Long> random_ids, TLRPC.Message resendMessage) {
|
||||
|
@ -1659,7 +1662,7 @@ public class SecretChatHelper extends BaseController {
|
|||
getMessagesStorage().updateEncryptedChat(newChat);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat);
|
||||
});
|
||||
declineSecretChat(chat.id);
|
||||
declineSecretChat(chat.id, false);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1733,7 +1736,7 @@ public class SecretChatHelper extends BaseController {
|
|||
BigInteger i_authKey = new BigInteger(1, encryptedChat.g_a_or_b);
|
||||
|
||||
if (!Utilities.isGoodGaAndGb(i_authKey, p)) {
|
||||
declineSecretChat(encryptedChat.id);
|
||||
declineSecretChat(encryptedChat.id, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1789,13 +1792,14 @@ public class SecretChatHelper extends BaseController {
|
|||
getMessagesController().putEncryptedChat(newChat, false);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.encryptedChatUpdated, newChat);
|
||||
});
|
||||
declineSecretChat(encryptedChat.id);
|
||||
declineSecretChat(encryptedChat.id, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void declineSecretChat(int chat_id) {
|
||||
public void declineSecretChat(int chat_id, boolean revoke) {
|
||||
TLRPC.TL_messages_discardEncryption req = new TLRPC.TL_messages_discardEncryption();
|
||||
req.chat_id = chat_id;
|
||||
req.delete_history = revoke;
|
||||
getConnectionsManager().sendRequest(req, (response, error) -> {
|
||||
|
||||
});
|
||||
|
@ -1815,7 +1819,7 @@ public class SecretChatHelper extends BaseController {
|
|||
if (response instanceof TLRPC.TL_messages_dhConfig) {
|
||||
if (!Utilities.isGoodPrime(res.p, res.g)) {
|
||||
acceptingChats.remove(encryptedChat.id);
|
||||
declineSecretChat(encryptedChat.id);
|
||||
declineSecretChat(encryptedChat.id, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1838,7 +1842,7 @@ public class SecretChatHelper extends BaseController {
|
|||
|
||||
if (!Utilities.isGoodGaAndGb(g_a, p)) {
|
||||
acceptingChats.remove(encryptedChat.id);
|
||||
declineSecretChat(encryptedChat.id);
|
||||
declineSecretChat(encryptedChat.id, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.telegram.messenger;
|
|||
|
||||
import android.content.ClipDescription;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.PorterDuff;
|
||||
|
@ -67,10 +68,12 @@ import java.io.FileInputStream;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
@ -90,6 +93,169 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
private HashMap<String, Boolean> waitingForCallback = new HashMap<>();
|
||||
private HashMap<String, byte[]> waitingForVote = new HashMap<>();
|
||||
private LongSparseArray<Long> voteSendTime = new LongSparseArray();
|
||||
private HashMap<String, ImportingHistory> importingHistoryFiles = new HashMap<>();
|
||||
private LongSparseArray<ImportingHistory> importingHistoryMap = new LongSparseArray<>();
|
||||
|
||||
public class ImportingHistory {
|
||||
public String historyPath;
|
||||
public ArrayList<Uri> mediaPaths = new ArrayList<>();
|
||||
public HashMap<String, TLRPC.InputFile> uploadedMedias = new HashMap<>();
|
||||
public HashSet<String> uploadSet = new HashSet<>();
|
||||
public HashMap<String, Float> uploadProgresses = new HashMap<>();
|
||||
public HashMap<String, Long> uploadSize = new HashMap<>();
|
||||
public ArrayList<String> uploadMedia = new ArrayList<>();
|
||||
public TLRPC.InputPeer peer;
|
||||
public long totalSize;
|
||||
public long uploadedSize;
|
||||
public long dialogId;
|
||||
public long importId;
|
||||
public int uploadProgress;
|
||||
public double estimatedUploadSpeed;
|
||||
private long lastUploadTime;
|
||||
private long lastUploadSize;
|
||||
public int timeUntilFinish = Integer.MAX_VALUE;
|
||||
|
||||
private void initImport(TLRPC.InputFile inputFile) {
|
||||
TLRPC.TL_messages_initHistoryImport req = new TLRPC.TL_messages_initHistoryImport();
|
||||
req.file = inputFile;
|
||||
req.media_count = mediaPaths.size();
|
||||
req.peer = peer;
|
||||
getConnectionsManager().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (response instanceof TLRPC.TL_messages_historyImport) {
|
||||
importId = ((TLRPC.TL_messages_historyImport) response).id;
|
||||
uploadSet.remove(historyPath);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.historyImportProgressChanged, dialogId);
|
||||
if (uploadSet.isEmpty()) {
|
||||
startImport();
|
||||
}
|
||||
lastUploadTime = SystemClock.elapsedRealtime();
|
||||
for (int a = 0, N = uploadMedia.size(); a < N; a++) {
|
||||
getFileLoader().uploadFile(uploadMedia.get(a), false, true, ConnectionsManager.FileTypeFile);
|
||||
}
|
||||
} else {
|
||||
importingHistoryMap.remove(dialogId);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.historyImportProgressChanged, dialogId, req, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public long getUploadedCount() {
|
||||
return uploadedSize;
|
||||
}
|
||||
|
||||
public long getTotalCount() {
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
private void addUploadProgress(String path, long sz, float progress) {
|
||||
uploadProgresses.put(path, progress);
|
||||
uploadSize.put(path, sz);
|
||||
uploadedSize = 0;
|
||||
for (HashMap.Entry<String, Long> entry : uploadSize.entrySet()) {
|
||||
uploadedSize += entry.getValue();
|
||||
}
|
||||
long newTime = SystemClock.elapsedRealtime();
|
||||
if (!path.equals(historyPath) && uploadedSize != lastUploadSize && newTime != lastUploadTime) {
|
||||
double dt = (newTime - lastUploadTime) / 1000.0;
|
||||
double uploadSpeed = (uploadedSize - lastUploadSize) / dt;
|
||||
if (estimatedUploadSpeed == 0) {
|
||||
estimatedUploadSpeed = uploadSpeed;
|
||||
} else {
|
||||
double coef = 0.01;
|
||||
estimatedUploadSpeed = coef * uploadSpeed + (1 - coef) * estimatedUploadSpeed;
|
||||
}
|
||||
timeUntilFinish = (int) ((totalSize - uploadedSize) * 1000 / (double) estimatedUploadSpeed);
|
||||
lastUploadSize = uploadedSize;
|
||||
lastUploadTime = newTime;
|
||||
}
|
||||
float pr = getUploadedCount() / (float) getTotalCount();
|
||||
int newProgress = (int) (pr * 100);
|
||||
if (uploadProgress != newProgress) {
|
||||
uploadProgress = newProgress;
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.historyImportProgressChanged, dialogId);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMediaImport(String path, long size, TLRPC.InputFile inputFile) {
|
||||
addUploadProgress(path, size, 1.0f);
|
||||
uploadedMedias.put(path, inputFile);
|
||||
TLRPC.TL_messages_uploadImportedMedia req = new TLRPC.TL_messages_uploadImportedMedia();
|
||||
req.peer = peer;
|
||||
req.import_id = importId;
|
||||
req.file_name = new File(path).getName();
|
||||
|
||||
MimeTypeMap myMime = MimeTypeMap.getSingleton();
|
||||
String ext = "txt";
|
||||
int idx = req.file_name.lastIndexOf('.');
|
||||
if (idx != -1) {
|
||||
ext = req.file_name.substring(idx + 1).toLowerCase();
|
||||
}
|
||||
String mimeType = myMime.getMimeTypeFromExtension(ext);
|
||||
if (mimeType == null) {
|
||||
if ("opus".equals(ext)) {
|
||||
mimeType = "audio/opus";
|
||||
} else if ("webp".equals(ext)) {
|
||||
mimeType = "image/webp";
|
||||
} else {
|
||||
mimeType = "text/plain";
|
||||
}
|
||||
}
|
||||
if (mimeType.equals("image/jpg") || mimeType.equals("image/jpeg")) {
|
||||
TLRPC.TL_inputMediaUploadedPhoto inputMediaUploadedPhoto = new TLRPC.TL_inputMediaUploadedPhoto();
|
||||
inputMediaUploadedPhoto.file = inputFile;
|
||||
req.media = inputMediaUploadedPhoto;
|
||||
} else {
|
||||
TLRPC.TL_inputMediaUploadedDocument inputMediaDocument = new TLRPC.TL_inputMediaUploadedDocument();
|
||||
inputMediaDocument.file = inputFile;
|
||||
inputMediaDocument.mime_type = mimeType;
|
||||
req.media = inputMediaDocument;
|
||||
}
|
||||
|
||||
getConnectionsManager().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
uploadSet.remove(path);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.historyImportProgressChanged, dialogId);
|
||||
if (uploadSet.isEmpty()) {
|
||||
startImport();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startImport() {
|
||||
TLRPC.TL_messages_startHistoryImport req = new TLRPC.TL_messages_startHistoryImport();
|
||||
req.peer = peer;
|
||||
req.import_id = importId;
|
||||
getConnectionsManager().sendRequest(req, new RequestDelegate() {
|
||||
@Override
|
||||
public void run(TLObject response, TLRPC.TL_error error) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
importingHistoryMap.remove(dialogId);
|
||||
if (error == null) {
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.historyImportProgressChanged, dialogId);
|
||||
} else {
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.historyImportProgressChanged, dialogId, req, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setImportProgress(int value) {
|
||||
if (value == 100) {
|
||||
importingHistoryMap.remove(dialogId);
|
||||
}
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.historyImportProgressChanged, dialogId);
|
||||
}
|
||||
}
|
||||
|
||||
private static DispatchQueue mediaSendQueue = new DispatchQueue("mediaSendQueue");
|
||||
private static ThreadPoolExecutor mediaSendThreadPool;
|
||||
|
@ -421,6 +587,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
getNotificationCenter().addObserver(SendMessagesHelper.this, NotificationCenter.FileDidUpload);
|
||||
getNotificationCenter().addObserver(SendMessagesHelper.this, NotificationCenter.FileUploadProgressChanged);
|
||||
getNotificationCenter().addObserver(SendMessagesHelper.this, NotificationCenter.FileDidFailUpload);
|
||||
getNotificationCenter().addObserver(SendMessagesHelper.this, NotificationCenter.filePreparingStarted);
|
||||
getNotificationCenter().addObserver(SendMessagesHelper.this, NotificationCenter.fileNewChunkAvailable);
|
||||
|
@ -443,15 +610,35 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
waitingForLocation.clear();
|
||||
waitingForCallback.clear();
|
||||
waitingForVote.clear();
|
||||
importingHistoryFiles.clear();
|
||||
importingHistoryMap.clear();
|
||||
locationProvider.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didReceivedNotification(int id, int account, final Object... args) {
|
||||
if (id == NotificationCenter.FileDidUpload) {
|
||||
if (id == NotificationCenter.FileUploadProgressChanged) {
|
||||
String fileName = (String) args[0];
|
||||
ImportingHistory importingHistory = importingHistoryFiles.get(fileName);
|
||||
if (importingHistory != null) {
|
||||
Long loadedSize = (Long) args[1];
|
||||
Long totalSize = (Long) args[2];
|
||||
importingHistory.addUploadProgress(fileName, loadedSize, loadedSize / (float) totalSize);
|
||||
}
|
||||
} else if (id == NotificationCenter.FileDidUpload) {
|
||||
final String location = (String) args[0];
|
||||
final TLRPC.InputFile file = (TLRPC.InputFile) args[1];
|
||||
final TLRPC.InputEncryptedFile encryptedFile = (TLRPC.InputEncryptedFile) args[2];
|
||||
|
||||
ImportingHistory importingHistory = importingHistoryFiles.get(location);
|
||||
if (importingHistory != null) {
|
||||
if (location.equals(importingHistory.historyPath)) {
|
||||
importingHistory.initImport(file);
|
||||
} else {
|
||||
importingHistory.onMediaImport(location, (Long) args[5], file);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<DelayedMessage> arr = delayedMessages.get(location);
|
||||
if (arr != null) {
|
||||
for (int a = 0; a < arr.size(); a++) {
|
||||
|
@ -4007,7 +4194,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
}
|
||||
putToDelayedMessages(location, message);
|
||||
if (message.obj.videoEditedInfo != null && message.obj.videoEditedInfo.needConvert()) {
|
||||
getFileLoader().uploadFile(location, false, false, document.size, ConnectionsManager.FileTypeVideo);
|
||||
getFileLoader().uploadFile(location, false, false, document.size, ConnectionsManager.FileTypeVideo, false);
|
||||
} else {
|
||||
getFileLoader().uploadFile(location, false, false, ConnectionsManager.FileTypeVideo);
|
||||
}
|
||||
|
@ -4034,7 +4221,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
}
|
||||
putToDelayedMessages(location, message);
|
||||
if (message.obj.videoEditedInfo != null && message.obj.videoEditedInfo.needConvert()) {
|
||||
getFileLoader().uploadFile(location, true, false, document.size, ConnectionsManager.FileTypeVideo);
|
||||
getFileLoader().uploadFile(location, true, false, document.size, ConnectionsManager.FileTypeVideo, false);
|
||||
} else {
|
||||
getFileLoader().uploadFile(location, true, false, ConnectionsManager.FileTypeVideo);
|
||||
}
|
||||
|
@ -4126,7 +4313,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
message.extraHashMap.put(documentLocation + "_t", message.photoSize);
|
||||
}
|
||||
if (messageObject.videoEditedInfo != null && messageObject.videoEditedInfo.needConvert()) {
|
||||
getFileLoader().uploadFile(documentLocation, false, false, document.size, ConnectionsManager.FileTypeVideo);
|
||||
getFileLoader().uploadFile(documentLocation, false, false, document.size, ConnectionsManager.FileTypeVideo, false);
|
||||
} else {
|
||||
getFileLoader().uploadFile(documentLocation, false, false, ConnectionsManager.FileTypeVideo);
|
||||
}
|
||||
|
@ -4150,7 +4337,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
message.extraHashMap.put(documentLocation + "_t", message.photoSize);
|
||||
}
|
||||
if (messageObject.videoEditedInfo != null && messageObject.videoEditedInfo.needConvert()) {
|
||||
getFileLoader().uploadFile(documentLocation, true, false, document.size, ConnectionsManager.FileTypeVideo);
|
||||
getFileLoader().uploadFile(documentLocation, true, false, document.size, ConnectionsManager.FileTypeVideo, false);
|
||||
} else {
|
||||
getFileLoader().uploadFile(documentLocation, true, false, ConnectionsManager.FileTypeVideo);
|
||||
}
|
||||
|
@ -5231,6 +5418,95 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
});
|
||||
}
|
||||
|
||||
public ImportingHistory getImportingHistory(long dialogId) {
|
||||
return importingHistoryMap.get(dialogId);
|
||||
}
|
||||
|
||||
public boolean isImportingHistory() {
|
||||
return importingHistoryMap.size() != 0;
|
||||
}
|
||||
|
||||
public void prepareImportHistory(long dialogId, Uri uri, ArrayList<Uri> mediaUris, MessagesStorage.IntCallback onStartImport) {
|
||||
if (importingHistoryMap.get(dialogId) != null) {
|
||||
onStartImport.run(0);
|
||||
return;
|
||||
}
|
||||
int lowerId = (int) dialogId;
|
||||
if (lowerId < 0) {
|
||||
TLRPC.Chat chat = getMessagesController().getChat(-lowerId);
|
||||
if (chat != null && !chat.megagroup) {
|
||||
getMessagesController().convertToMegaGroup(null, -lowerId, null, (chatId) -> {
|
||||
if (chatId != 0) {
|
||||
prepareImportHistory(-chatId, uri, mediaUris, onStartImport);
|
||||
} else {
|
||||
onStartImport.run(0);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
new Thread(() -> {
|
||||
ArrayList<Uri> uris = mediaUris != null ? mediaUris : new ArrayList<>();
|
||||
ImportingHistory importingHistory = new ImportingHistory();
|
||||
importingHistory.mediaPaths = uris;
|
||||
importingHistory.dialogId = dialogId;
|
||||
importingHistory.peer = getMessagesController().getInputPeer((int) dialogId);
|
||||
HashMap<String, ImportingHistory> files = new HashMap<>();
|
||||
for (int a = 0, N = uris.size(); a < N + 1; a++) {
|
||||
Uri mediaUri;
|
||||
if (a == 0) {
|
||||
mediaUri = uri;
|
||||
} else {
|
||||
mediaUri = uris.get(a - 1);
|
||||
}
|
||||
if (mediaUri == null || AndroidUtilities.isInternalUri(mediaUri)) {
|
||||
if (a == 0) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
onStartImport.run(0);
|
||||
});
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
String path = MediaController.copyFileToCache(mediaUri, "txt");
|
||||
final File f = new File(path);
|
||||
long size;
|
||||
if (!f.exists() || (size = f.length()) == 0) {
|
||||
if (a == 0) {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
onStartImport.run(0);
|
||||
});
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
importingHistory.totalSize += size;
|
||||
if (a == 0) {
|
||||
importingHistory.historyPath = path;
|
||||
} else {
|
||||
importingHistory.uploadMedia.add(path);
|
||||
}
|
||||
importingHistory.uploadSet.add(path);
|
||||
files.put(path, importingHistory);
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
importingHistoryFiles.putAll(files);
|
||||
importingHistoryMap.put(dialogId, importingHistory);
|
||||
getFileLoader().uploadFile(importingHistory.historyPath, false, true, 0, ConnectionsManager.FileTypeFile, true);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.historyImportProgressChanged, dialogId);
|
||||
onStartImport.run((int) dialogId);
|
||||
|
||||
Intent intent = new Intent(ApplicationLoader.applicationContext, ImportingService.class);
|
||||
try {
|
||||
ApplicationLoader.applicationContext.startService(intent);
|
||||
} catch (Throwable e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
}).start();
|
||||
}
|
||||
|
||||
public TLRPC.TL_photo generatePhotoSizes(String path, Uri imageUri) {
|
||||
return generatePhotoSizes(null, path, imageUri);
|
||||
}
|
||||
|
@ -5501,9 +5777,13 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
params.put("parentObject", parentFinal);
|
||||
}
|
||||
Integer prevType = 0;
|
||||
boolean isSticker = false;
|
||||
if (docType != null) {
|
||||
prevType = docType[0];
|
||||
if (document.mime_type != null && (document.mime_type.toLowerCase().startsWith("image/") || document.mime_type.toLowerCase().startsWith("video/mp4")) || MessageObject.canPreviewDocument(document)) {
|
||||
if (document.mime_type != null && document.mime_type.toLowerCase().startsWith("image/webp")) {
|
||||
docType[0] = -1;
|
||||
isSticker = true;
|
||||
} else if (document.mime_type != null && (document.mime_type.toLowerCase().startsWith("image/") || document.mime_type.toLowerCase().startsWith("video/mp4")) || MessageObject.canPreviewDocument(document)) {
|
||||
docType[0] = 1;
|
||||
} else if (attributeAudio != null) {
|
||||
docType[0] = 2;
|
||||
|
@ -5516,9 +5796,11 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
finishGroup(accountInstance, groupId[0], scheduleDate);
|
||||
groupId[0] = Utilities.random.nextLong();
|
||||
}
|
||||
params.put("groupId", "" + groupId[0]);
|
||||
if (isGroupFinal) {
|
||||
params.put("final", "1");
|
||||
if (!isSticker) {
|
||||
params.put("groupId", "" + groupId[0]);
|
||||
if (isGroupFinal) {
|
||||
params.put("final", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5685,7 +5967,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
if (!prepareSendingDocumentInternal(accountInstance, paths.get(a), originalPaths.get(a), null, mime, dialogId, replyToMsg, replyToTopMsg, captionFinal, null, editingMessageObject, groupId, mediaCount == 10 || a == count - 1, inputContent == null, notify, scheduleDate, docType)) {
|
||||
error = true;
|
||||
}
|
||||
if (prevGroupId != groupId[0]) {
|
||||
if (prevGroupId != groupId[0] || groupId[0] == -1) {
|
||||
mediaCount = 1;
|
||||
}
|
||||
}
|
||||
|
@ -5708,7 +5990,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
|
|||
if (!prepareSendingDocumentInternal(accountInstance, null, null, uris.get(a), mime, dialogId, replyToMsg, replyToTopMsg, captionFinal, null, editingMessageObject, groupId, mediaCount == 10 || a == count - 1, inputContent == null, notify, scheduleDate, docType)) {
|
||||
error = true;
|
||||
}
|
||||
if (prevGroupId != groupId[0]) {
|
||||
if (prevGroupId != groupId[0] || groupId[0] == -1) {
|
||||
mediaCount = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package org.telegram.messenger;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import org.telegram.ui.LaunchActivity;
|
||||
|
||||
public class ShortcutWidgetProvider extends AppWidgetProvider {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds);
|
||||
for (int i = 0; i < appWidgetIds.length; i++) {
|
||||
int appWidgetId = appWidgetIds[i];
|
||||
updateWidget(context, appWidgetManager, appWidgetId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(Context context, int[] appWidgetIds) {
|
||||
super.onDeleted(context, appWidgetIds);
|
||||
for (int a = 0; a < appWidgetIds.length; a++) {
|
||||
SharedPreferences preferences = context.getSharedPreferences("shortcut_widget", Activity.MODE_PRIVATE);
|
||||
int accountId = preferences.getInt("account" + appWidgetIds[a], -1);
|
||||
if (accountId >= 0) {
|
||||
AccountInstance accountInstance = AccountInstance.getInstance(accountId);
|
||||
accountInstance.getMessagesStorage().clearWidgetDialogs(appWidgetIds[a]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
|
||||
Intent intent2 = new Intent(context, ShortcutWidgetService.class);
|
||||
intent2.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
intent2.setData(Uri.parse(intent2.toUri(Intent.URI_INTENT_SCHEME)));
|
||||
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.shortcut_widget_layout);
|
||||
rv.setRemoteAdapter(appWidgetId, R.id.list_view, intent2);
|
||||
rv.setEmptyView(R.id.list_view, R.id.empty_view);
|
||||
|
||||
Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class);
|
||||
intent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
rv.setPendingIntentTemplate(R.id.list_view, contentIntent);
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, rv);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,353 @@
|
|||
package org.telegram.messenger;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.RemoteViewsService;
|
||||
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.AvatarDrawable;
|
||||
import org.telegram.ui.Components.ForegroundColorSpanThemable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ShortcutWidgetService extends RemoteViewsService {
|
||||
@Override
|
||||
public RemoteViewsFactory onGetViewFactory(Intent intent) {
|
||||
return new ShortcutRemoteViewsFactory(getApplicationContext(), intent);
|
||||
}
|
||||
}
|
||||
|
||||
class ShortcutRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
|
||||
|
||||
private ArrayList<Integer> dids = new ArrayList<>();
|
||||
private Context mContext;
|
||||
private int appWidgetId;
|
||||
private AccountInstance accountInstance;
|
||||
private Paint roundPaint;
|
||||
private RectF bitmapRect;
|
||||
private LongSparseArray<TLRPC.Dialog> dialogs = new LongSparseArray<>();
|
||||
private LongSparseArray<MessageObject> messageObjects = new LongSparseArray<>();
|
||||
|
||||
public ShortcutRemoteViewsFactory(Context context, Intent intent) {
|
||||
mContext = context;
|
||||
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||
SharedPreferences preferences = context.getSharedPreferences("shortcut_widget", Activity.MODE_PRIVATE);
|
||||
int accountId = preferences.getInt("account" + appWidgetId, -1);
|
||||
if (accountId >= 0) {
|
||||
accountInstance = AccountInstance.getInstance(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
public void onCreate() {
|
||||
ApplicationLoader.postInitApplication();
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return dids.size();
|
||||
}
|
||||
|
||||
public RemoteViews getViewAt(int position) {
|
||||
Integer id = dids.get(position);
|
||||
String name;
|
||||
|
||||
TLRPC.FileLocation photoPath = null;
|
||||
TLRPC.User user = null;
|
||||
TLRPC.Chat chat = null;
|
||||
if (id > 0) {
|
||||
user = accountInstance.getMessagesController().getUser(id);
|
||||
if (UserObject.isUserSelf(user)) {
|
||||
name = LocaleController.getString("SavedMessages", R.string.SavedMessages);
|
||||
} else if (UserObject.isReplyUser(user)) {
|
||||
name = LocaleController.getString("RepliesTitle", R.string.RepliesTitle);
|
||||
} else {
|
||||
name = ContactsController.formatName(user.first_name, user.last_name);
|
||||
}
|
||||
if (!UserObject.isReplyUser(user) && !UserObject.isUserSelf(user) && user.photo != null && user.photo.photo_small != null && user.photo.photo_small.volume_id != 0 && user.photo.photo_small.local_id != 0) {
|
||||
photoPath = user.photo.photo_small;
|
||||
}
|
||||
} else {
|
||||
chat = accountInstance.getMessagesController().getChat(-id);
|
||||
name = chat.title;
|
||||
if (chat.photo != null && chat.photo.photo_small != null && chat.photo.photo_small.volume_id != 0 && chat.photo.photo_small.local_id != 0) {
|
||||
photoPath = chat.photo.photo_small;
|
||||
}
|
||||
}
|
||||
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.shortcut_widget_item);
|
||||
rv.setTextViewText(R.id.shortcut_widget_item_text, name);
|
||||
|
||||
try {
|
||||
Bitmap bitmap = null;
|
||||
if (photoPath != null) {
|
||||
File path = FileLoader.getPathToAttach(photoPath, true);
|
||||
bitmap = BitmapFactory.decodeFile(path.toString());
|
||||
}
|
||||
|
||||
int size = AndroidUtilities.dp(48);
|
||||
Bitmap result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
result.eraseColor(Color.TRANSPARENT);
|
||||
Canvas canvas = new Canvas(result);
|
||||
if (bitmap == null) {
|
||||
AvatarDrawable avatarDrawable;
|
||||
if (user != null) {
|
||||
avatarDrawable = new AvatarDrawable(user);
|
||||
if (UserObject.isReplyUser(user)) {
|
||||
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
|
||||
} else if (UserObject.isUserSelf(user)) {
|
||||
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
|
||||
}
|
||||
} else {
|
||||
avatarDrawable = new AvatarDrawable(chat);
|
||||
}
|
||||
avatarDrawable.setBounds(0, 0, size, size);
|
||||
avatarDrawable.draw(canvas);
|
||||
} else {
|
||||
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
if (roundPaint == null) {
|
||||
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
bitmapRect = new RectF();
|
||||
}
|
||||
float scale = size / (float) bitmap.getWidth();
|
||||
canvas.save();
|
||||
canvas.scale(scale, scale);
|
||||
roundPaint.setShader(shader);
|
||||
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint);
|
||||
canvas.restore();
|
||||
}
|
||||
canvas.setBitmap(null);
|
||||
rv.setImageViewBitmap(R.id.shortcut_widget_item_avatar, result);
|
||||
} catch (Throwable e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
|
||||
MessageObject message = messageObjects.get(id);
|
||||
TLRPC.Dialog dialog = dialogs.get(id);
|
||||
if (message != null) {
|
||||
TLRPC.User fromUser = null;
|
||||
TLRPC.Chat fromChat = null;
|
||||
int fromId = message.getFromChatId();
|
||||
if (fromId > 0) {
|
||||
fromUser = accountInstance.getMessagesController().getUser(fromId);
|
||||
} else {
|
||||
fromChat = accountInstance.getMessagesController().getChat(-fromId);
|
||||
}
|
||||
CharSequence messageString;
|
||||
CharSequence messageNameString;
|
||||
int textColor = 0xff212121;
|
||||
if (message.messageOwner instanceof TLRPC.TL_messageService) {
|
||||
if (ChatObject.isChannel(chat) && (message.messageOwner.action instanceof TLRPC.TL_messageActionHistoryClear ||
|
||||
message.messageOwner.action instanceof TLRPC.TL_messageActionChannelMigrateFrom)) {
|
||||
messageString = "";
|
||||
} else {
|
||||
messageString = message.messageText;
|
||||
}
|
||||
textColor = 0xff3c7eb0;
|
||||
} else {
|
||||
boolean needEmoji = true;
|
||||
if (chat != null && chat.id > 0 && fromChat == null && (!ChatObject.isChannel(chat) || ChatObject.isMegagroup(chat))) {
|
||||
if (message.isOutOwner()) {
|
||||
messageNameString = LocaleController.getString("FromYou", R.string.FromYou);
|
||||
} else if (fromUser != null) {
|
||||
messageNameString = UserObject.getFirstName(fromUser).replace("\n", "");
|
||||
} else {
|
||||
messageNameString = "DELETED";
|
||||
}
|
||||
SpannableStringBuilder stringBuilder;
|
||||
String messageFormat = "%2$s: \u2068%1$s\u2069";
|
||||
if (message.caption != null) {
|
||||
String mess = message.caption.toString();
|
||||
if (mess.length() > 150) {
|
||||
mess = mess.substring(0, 150);
|
||||
}
|
||||
String emoji;
|
||||
if (message.isVideo()) {
|
||||
emoji = "\uD83D\uDCF9 ";
|
||||
} else if (message.isVoice()) {
|
||||
emoji = "\uD83C\uDFA4 ";
|
||||
} else if (message.isMusic()) {
|
||||
emoji = "\uD83C\uDFA7 ";
|
||||
} else if (message.isPhoto()) {
|
||||
emoji = "\uD83D\uDDBC ";
|
||||
} else {
|
||||
emoji = "\uD83D\uDCCE ";
|
||||
}
|
||||
stringBuilder = SpannableStringBuilder.valueOf(String.format(messageFormat, emoji + mess.replace('\n', ' '), messageNameString));
|
||||
} else if (message.messageOwner.media != null && !message.isMediaEmpty()) {
|
||||
textColor = 0xff3c7eb0;
|
||||
String innerMessage;
|
||||
if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
|
||||
TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) message.messageOwner.media;
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
innerMessage = String.format("\uD83D\uDCCA \u2068%s\u2069", mediaPoll.poll.question);
|
||||
} else {
|
||||
innerMessage = String.format("\uD83D\uDCCA %s", mediaPoll.poll.question);
|
||||
}
|
||||
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaGame) {
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
innerMessage = String.format("\uD83C\uDFAE \u2068%s\u2069", message.messageOwner.media.game.title);
|
||||
} else {
|
||||
innerMessage = String.format("\uD83C\uDFAE %s", message.messageOwner.media.game.title);
|
||||
}
|
||||
} else if (message.type == 14) {
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
innerMessage = String.format("\uD83C\uDFA7 \u2068%s - %s\u2069", message.getMusicAuthor(), message.getMusicTitle());
|
||||
} else {
|
||||
innerMessage = String.format("\uD83C\uDFA7 %s - %s", message.getMusicAuthor(), message.getMusicTitle());
|
||||
}
|
||||
} else {
|
||||
innerMessage = message.messageText.toString();
|
||||
}
|
||||
innerMessage = innerMessage.replace('\n', ' ');
|
||||
stringBuilder = SpannableStringBuilder.valueOf(String.format(messageFormat, innerMessage, messageNameString));
|
||||
try {
|
||||
stringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_chats_attachMessage), messageNameString.length() + 2, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
} else if (message.messageOwner.message != null) {
|
||||
String mess = message.messageOwner.message;
|
||||
if (mess.length() > 150) {
|
||||
mess = mess.substring(0, 150);
|
||||
}
|
||||
mess = mess.replace('\n', ' ').trim();
|
||||
stringBuilder = SpannableStringBuilder.valueOf(String.format(messageFormat, mess, messageNameString));
|
||||
} else {
|
||||
stringBuilder = SpannableStringBuilder.valueOf("");
|
||||
}
|
||||
try {
|
||||
stringBuilder.setSpan(new ForegroundColorSpanThemable(Theme.key_chats_nameMessage), 0, messageNameString.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
messageString = stringBuilder;//Emoji.replaceEmoji(stringBuilder, Theme.dialogs_messagePaint[paintIndex].getFontMetricsInt(), AndroidUtilities.dp(20), false);
|
||||
} else {
|
||||
if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && message.messageOwner.media.photo instanceof TLRPC.TL_photoEmpty && message.messageOwner.media.ttl_seconds != 0) {
|
||||
messageString = LocaleController.getString("AttachPhotoExpired", R.string.AttachPhotoExpired);
|
||||
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && message.messageOwner.media.document instanceof TLRPC.TL_documentEmpty && message.messageOwner.media.ttl_seconds != 0) {
|
||||
messageString = LocaleController.getString("AttachVideoExpired", R.string.AttachVideoExpired);
|
||||
} else if (message.caption != null) {
|
||||
String emoji;
|
||||
if (message.isVideo()) {
|
||||
emoji = "\uD83D\uDCF9 ";
|
||||
} else if (message.isVoice()) {
|
||||
emoji = "\uD83C\uDFA4 ";
|
||||
} else if (message.isMusic()) {
|
||||
emoji = "\uD83C\uDFA7 ";
|
||||
} else if (message.isPhoto()) {
|
||||
emoji = "\uD83D\uDDBC ";
|
||||
} else {
|
||||
emoji = "\uD83D\uDCCE ";
|
||||
}
|
||||
messageString = emoji + message.caption;
|
||||
} else {
|
||||
if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
|
||||
TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) message.messageOwner.media;
|
||||
messageString = "\uD83D\uDCCA " + mediaPoll.poll.question;
|
||||
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaGame) {
|
||||
messageString = "\uD83C\uDFAE " + message.messageOwner.media.game.title;
|
||||
} else if (message.type == 14) {
|
||||
messageString = String.format("\uD83C\uDFA7 %s - %s", message.getMusicAuthor(), message.getMusicTitle());
|
||||
} else {
|
||||
messageString = message.messageText;
|
||||
AndroidUtilities.highlightText(messageString, message.highlightedWords);
|
||||
}
|
||||
if (message.messageOwner.media != null && !message.isMediaEmpty()) {
|
||||
textColor = 0xff3c7eb0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv.setTextViewText(R.id.shortcut_widget_item_time, LocaleController.stringForMessageListDate(message.messageOwner.date));
|
||||
rv.setTextViewText(R.id.shortcut_widget_item_message, messageString);
|
||||
rv.setTextColor(R.id.shortcut_widget_item_message, textColor);
|
||||
} else {
|
||||
if (dialog != null) {
|
||||
rv.setTextViewText(R.id.shortcut_widget_item_time, LocaleController.stringForMessageListDate(dialog.last_message_date));
|
||||
}
|
||||
}
|
||||
if (dialog != null && dialog.unread_count > 0) {
|
||||
rv.setTextViewText(R.id.shortcut_widget_item_badge, String.format("%d", dialog.unread_count));
|
||||
rv.setViewVisibility(R.id.shortcut_widget_item_badge, View.VISIBLE);
|
||||
} else {
|
||||
rv.setViewVisibility(R.id.shortcut_widget_item_badge, View.GONE);
|
||||
}
|
||||
|
||||
Bundle extras = new Bundle();
|
||||
|
||||
if (id > 0) {
|
||||
extras.putInt("userId", id);
|
||||
} else {
|
||||
extras.putInt("chatId", -id);
|
||||
}
|
||||
extras.putInt("currentAccount", accountInstance.getCurrentAccount());
|
||||
|
||||
Intent fillInIntent = new Intent();
|
||||
fillInIntent.putExtras(extras);
|
||||
rv.setOnClickFillInIntent(R.id.shortcut_widget_item, fillInIntent);
|
||||
|
||||
rv.setViewVisibility(R.id.shortcut_widget_item_divider, position == getCount() ? View.GONE : View.VISIBLE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
public RemoteViews getLoadingView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getViewTypeCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onDataSetChanged() {
|
||||
dids.clear();
|
||||
messageObjects.clear();
|
||||
if (accountInstance == null || !accountInstance.getUserConfig().isClientActivated()) {
|
||||
return;
|
||||
}
|
||||
ArrayList<TLRPC.User> users = new ArrayList<>();
|
||||
ArrayList<TLRPC.Chat> chats = new ArrayList<>();
|
||||
LongSparseArray<TLRPC.Message> messages = new LongSparseArray<>();
|
||||
accountInstance.getMessagesStorage().getWidgetDialogs(appWidgetId, dids, dialogs, messages, users, chats);
|
||||
accountInstance.getMessagesController().putUsers(users, true);
|
||||
accountInstance.getMessagesController().putChats(chats, true);
|
||||
messageObjects.clear();
|
||||
for (int a = 0, N = messages.size(); a < N; a++) {
|
||||
MessageObject messageObject = new MessageObject(accountInstance.getCurrentAccount(), messages.valueAt(a), (SparseArray<TLRPC.User>) null, null, false, true);
|
||||
messageObjects.put(messages.keyAt(a), messageObject);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -95,11 +95,11 @@ public final class Instance {
|
|||
instance = null;
|
||||
}
|
||||
|
||||
public static NativeInstance makeInstance(String version, Config config, String persistentStateFilePath, Endpoint[] endpoints, Proxy proxy, int networkType, EncryptionKey encryptionKey, VideoSink remoteSink, long videoCapturer) {
|
||||
public static NativeInstance makeInstance(String version, Config config, String persistentStateFilePath, Endpoint[] endpoints, Proxy proxy, int networkType, EncryptionKey encryptionKey, VideoSink remoteSink, long videoCapturer, NativeInstance.AudioLevelsCallback audioLevelsCallback) {
|
||||
if (!"2.4.4".equals(version)) {
|
||||
ContextUtils.initialize(ApplicationLoader.applicationContext);
|
||||
}
|
||||
instance = NativeInstance.make(version, config, persistentStateFilePath, endpoints, proxy, networkType, encryptionKey, remoteSink, videoCapturer);
|
||||
instance = NativeInstance.make(version, config, persistentStateFilePath, endpoints, proxy, networkType, encryptionKey, remoteSink, videoCapturer, audioLevelsCallback);
|
||||
setGlobalServerConfig(globalServerConfig.jsonObject.toString());
|
||||
setBufferSize(bufferSize);
|
||||
return instance;
|
||||
|
|
|
@ -35,12 +35,13 @@ public class NativeInstance {
|
|||
void run(int[] uids, float[] levels, boolean[] voice);
|
||||
}
|
||||
|
||||
public static NativeInstance make(String version, Instance.Config config, String path, Instance.Endpoint[] endpoints, Instance.Proxy proxy, int networkType, Instance.EncryptionKey encryptionKey, VideoSink remoteSink, long videoCapturer) {
|
||||
public static NativeInstance make(String version, Instance.Config config, String path, Instance.Endpoint[] endpoints, Instance.Proxy proxy, int networkType, Instance.EncryptionKey encryptionKey, VideoSink remoteSink, long videoCapturer, AudioLevelsCallback audioLevelsCallback) {
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("create new tgvoip instance, version " + version);
|
||||
}
|
||||
NativeInstance instance = new NativeInstance();
|
||||
instance.persistentStateFilePath = path;
|
||||
instance.audioLevelsCallback = audioLevelsCallback;
|
||||
float aspectRatio = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) / (float) Math.max(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y);
|
||||
instance.nativePtr = makeNativeInstance(version, instance, config, path, endpoints, proxy, networkType, encryptionKey, remoteSink, videoCapturer, aspectRatio);
|
||||
return instance;
|
||||
|
@ -112,7 +113,7 @@ public class NativeInstance {
|
|||
}
|
||||
|
||||
private void onAudioLevelsUpdated(int[] uids, float[] levels, boolean[] voice) {
|
||||
if (uids.length == 0) {
|
||||
if (isGroup && uids != null && uids.length == 0) {
|
||||
return;
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(() -> audioLevelsCallback.run(uids, levels, voice));
|
||||
|
@ -178,6 +179,7 @@ public class NativeInstance {
|
|||
public native String getVersion();
|
||||
public native void setNetworkType(int networkType);
|
||||
public native void setMuteMicrophone(boolean muteMicrophone);
|
||||
public native void setVolume(int ssrc, double volume);
|
||||
public native void setAudioOutputGainControlEnabled(boolean enabled);
|
||||
public native void setEchoCancellationStrength(int strength);
|
||||
public native String getLastError();
|
||||
|
|
|
@ -148,6 +148,7 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
|||
protected PowerManager.WakeLock cpuWakelock;
|
||||
protected boolean isProximityNear;
|
||||
protected boolean isHeadsetPlugged;
|
||||
protected int previousAudioOutput;
|
||||
protected ArrayList<StateListener> stateListeners = new ArrayList<>();
|
||||
protected MediaPlayer ringtonePlayer;
|
||||
protected Vibrator vibrator;
|
||||
|
@ -275,6 +276,22 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
|||
if (isHeadsetPlugged && proximityWakelock != null && proximityWakelock.isHeld()) {
|
||||
proximityWakelock.release();
|
||||
}
|
||||
if (isHeadsetPlugged) {
|
||||
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
|
||||
if (am.isSpeakerphoneOn()) {
|
||||
previousAudioOutput = 0;
|
||||
} else if (am.isBluetoothScoOn()) {
|
||||
previousAudioOutput = 2;
|
||||
} else {
|
||||
previousAudioOutput = 1;
|
||||
}
|
||||
setAudioOutput(1);
|
||||
} else {
|
||||
if (previousAudioOutput >= 0) {
|
||||
setAudioOutput(previousAudioOutput);
|
||||
previousAudioOutput = -1;
|
||||
}
|
||||
}
|
||||
isProximityNear = false;
|
||||
updateOutputGainControlState();
|
||||
} else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
|
||||
|
@ -416,7 +433,7 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
|||
}
|
||||
}
|
||||
if (send) {
|
||||
editCallMember(UserConfig.getInstance(currentAccount).getCurrentUser(), mute);
|
||||
editCallMember(UserConfig.getInstance(currentAccount).getCurrentUser(), mute, -1);
|
||||
Utilities.globalQueue.postRunnable(updateNotificationRunnable = () -> {
|
||||
if (updateNotificationRunnable == null) {
|
||||
return;
|
||||
|
@ -435,7 +452,7 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
|||
}
|
||||
}
|
||||
|
||||
public void editCallMember(TLObject object, boolean mute) {
|
||||
public void editCallMember(TLObject object, boolean mute, int volume) {
|
||||
if (groupCall == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -452,6 +469,10 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
|||
}
|
||||
}
|
||||
req.muted = mute;
|
||||
if (volume >= 0) {
|
||||
req.volume = volume;
|
||||
req.flags |= 2;
|
||||
}
|
||||
int account = currentAccount;
|
||||
AccountInstance.getInstance(account).getConnectionsManager().sendRequest(req, (response, error) -> {
|
||||
if (response != null) {
|
||||
|
@ -1554,8 +1575,8 @@ public abstract class VoIPBaseService extends Service implements SensorEventList
|
|||
if (groupCall == null) {
|
||||
Utilities.globalQueue.postRunnable(() -> soundPool.play(spEndId, 1, 1, 0, 0, 1));
|
||||
} else {
|
||||
Utilities.globalQueue.postRunnable(() -> soundPool.play(spVoiceChatEndId, 1.0f, 1.0f, 0, 0, 1));
|
||||
delay = 400;
|
||||
Utilities.globalQueue.postRunnable(() -> soundPool.play(spVoiceChatEndId, 1.0f, 1.0f, 0, 0, 1), 100);
|
||||
delay = 500;
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(afterSoundRunnable, delay);
|
||||
}
|
||||
|
|
|
@ -1374,16 +1374,34 @@ public class VoIPService extends VoIPBaseService {
|
|||
playedConnectedSound = true;
|
||||
}
|
||||
if (!wasConnected) {
|
||||
if (!micMute) {
|
||||
tgVoip.setMuteMicrophone(false);
|
||||
}
|
||||
wasConnected = true;
|
||||
NativeInstance instance = tgVoip;
|
||||
if (instance != null) {
|
||||
if (!micMute) {
|
||||
tgVoip.setMuteMicrophone(false);
|
||||
}
|
||||
for (int a = 0, N = groupCall.participants.size(); a < N; a++) {
|
||||
TLRPC.TL_groupCallParticipant participant = groupCall.participants.valueAt(a);
|
||||
if (participant.source == 0) {
|
||||
continue;
|
||||
}
|
||||
if (participant.muted_by_you) {
|
||||
instance.setVolume(participant.source, 0);
|
||||
} else {
|
||||
instance.setVolume(participant.source, ChatObject.getParticipantVolume(participant) / 10000.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
dispatchStateChanged(STATE_WAIT_INIT);
|
||||
}
|
||||
|
||||
public void setParticipantVolume(int ssrc, int volume) {
|
||||
tgVoip.setVolume(ssrc, volume / 10000.0);
|
||||
}
|
||||
|
||||
private void initiateActualEncryptedCall() {
|
||||
if (timeoutRunnable != null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(timeoutRunnable);
|
||||
|
@ -1490,7 +1508,12 @@ public class VoIPService extends VoIPBaseService {
|
|||
videoState = Instance.VIDEO_STATE_INACTIVE;
|
||||
}
|
||||
// init
|
||||
tgVoip = Instance.makeInstance(privateCall.protocol.library_versions.get(0), config, persistentStateFilePath, endpoints, proxy, getNetworkType(), encryptionKey, remoteSink, videoCapturer);
|
||||
tgVoip = Instance.makeInstance(privateCall.protocol.library_versions.get(0), config, persistentStateFilePath, endpoints, proxy, getNetworkType(), encryptionKey, remoteSink, videoCapturer, (uids, levels, voice) -> {
|
||||
if (sharedInstance == null || privateCall == null) {
|
||||
return;
|
||||
}
|
||||
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.webRtcMicAmplitudeEvent, levels[0]);
|
||||
});
|
||||
tgVoip.setOnStateUpdatedListener(this::onConnectionStateChanged);
|
||||
tgVoip.setOnSignalBarsUpdatedListener(this::onSignalBarCountChanged);
|
||||
tgVoip.setOnSignalDataListener(this::onSignalingData);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,6 +16,8 @@ import android.widget.LinearLayout;
|
|||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.ui.Adapters.FiltersView;
|
||||
import org.telegram.ui.Components.RLottieDrawable;
|
||||
import org.telegram.ui.Components.RLottieImageView;
|
||||
|
||||
public class ActionBarMenu extends LinearLayout {
|
||||
|
||||
|
@ -86,7 +88,11 @@ public class ActionBarMenu extends LinearLayout {
|
|||
addView(menuItem, layoutParams);
|
||||
} else {
|
||||
if (drawable != null) {
|
||||
menuItem.iconView.setImageDrawable(drawable);
|
||||
if (drawable instanceof RLottieDrawable) {
|
||||
menuItem.iconView.setAnimation((RLottieDrawable) drawable);
|
||||
} else {
|
||||
menuItem.iconView.setImageDrawable(drawable);
|
||||
}
|
||||
} else if (icon != 0) {
|
||||
menuItem.iconView.setImageResource(icon);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ import android.widget.LinearLayout;
|
|||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ImageLocation;
|
||||
|
@ -67,6 +66,8 @@ import org.telegram.ui.Components.CombinedDrawable;
|
|||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||
import org.telegram.ui.Components.EditTextBoldCursor;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.RLottieDrawable;
|
||||
import org.telegram.ui.Components.RLottieImageView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -133,7 +134,7 @@ public class ActionBarMenuItem extends FrameLayout {
|
|||
private ArrayList<SearchFilterView> searchFilterViews = new ArrayList<>();
|
||||
private TextView searchFieldCaption;
|
||||
private ImageView clearButton;
|
||||
protected ImageView iconView;
|
||||
protected RLottieImageView iconView;
|
||||
protected TextView textView;
|
||||
private FrameLayout searchContainer;
|
||||
private boolean isSearchField;
|
||||
|
@ -188,7 +189,7 @@ public class ActionBarMenuItem extends FrameLayout {
|
|||
}
|
||||
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
|
||||
} else {
|
||||
iconView = new ImageView(context);
|
||||
iconView = new RLottieImageView(context);
|
||||
iconView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
iconView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
|
||||
addView(iconView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
|
@ -426,14 +427,18 @@ public class ActionBarMenuItem extends FrameLayout {
|
|||
}
|
||||
|
||||
public ActionBarMenuSubItem addSubItem(int id, int icon, CharSequence text) {
|
||||
return addSubItem(id, icon, text, false);
|
||||
return addSubItem(id, icon, null, text, false);
|
||||
}
|
||||
|
||||
public ActionBarMenuSubItem addSubItem(int id, int icon, CharSequence text, boolean needCheck) {
|
||||
return addSubItem(id, icon, null, text, needCheck);
|
||||
}
|
||||
|
||||
public ActionBarMenuSubItem addSubItem(int id, int icon, Drawable iconDrawable, CharSequence text, boolean needCheck) {
|
||||
createPopupLayout();
|
||||
|
||||
ActionBarMenuSubItem cell = new ActionBarMenuSubItem(getContext(), needCheck, false, false);
|
||||
cell.setTextAndIcon(text, icon);
|
||||
cell.setTextAndIcon(text, icon, iconDrawable);
|
||||
cell.setMinimumWidth(AndroidUtilities.dp(196));
|
||||
cell.setTag(id);
|
||||
popupLayout.addView(cell);
|
||||
|
@ -839,10 +844,14 @@ public class ActionBarMenuItem extends FrameLayout {
|
|||
if (iconView == null) {
|
||||
return;
|
||||
}
|
||||
iconView.setImageDrawable(drawable);
|
||||
if (drawable instanceof RLottieDrawable) {
|
||||
iconView.setAnimation((RLottieDrawable) drawable);
|
||||
} else {
|
||||
iconView.setImageDrawable(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
public ImageView getIconView() {
|
||||
public RLottieImageView getIconView() {
|
||||
return iconView;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.telegram.ui.ActionBar;
|
|||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
|
@ -19,6 +20,7 @@ import org.telegram.ui.Components.LayoutHelper;
|
|||
public class ActionBarMenuSubItem extends FrameLayout {
|
||||
|
||||
private TextView textView;
|
||||
private TextView subtextView;
|
||||
private ImageView imageView;
|
||||
private ImageView checkView;
|
||||
|
||||
|
@ -82,9 +84,17 @@ public class ActionBarMenuSubItem extends FrameLayout {
|
|||
}
|
||||
|
||||
public void setTextAndIcon(CharSequence text, int icon) {
|
||||
setTextAndIcon(text, icon, null);
|
||||
}
|
||||
|
||||
public void setTextAndIcon(CharSequence text, int icon, Drawable iconDrawable) {
|
||||
textView.setText(text);
|
||||
if (icon != 0 || checkView != null) {
|
||||
imageView.setImageResource(icon);
|
||||
if (icon != 0 || iconDrawable != null || checkView != null) {
|
||||
if (iconDrawable != null) {
|
||||
imageView.setImageDrawable(iconDrawable);
|
||||
} else {
|
||||
imageView.setImageResource(icon);
|
||||
}
|
||||
imageView.setVisibility(VISIBLE);
|
||||
textView.setPadding(LocaleController.isRTL ? 0 : AndroidUtilities.dp(43), 0, LocaleController.isRTL ? AndroidUtilities.dp(43) : 0, 0);
|
||||
} else {
|
||||
|
@ -118,10 +128,38 @@ public class ActionBarMenuSubItem extends FrameLayout {
|
|||
textView.setText(text);
|
||||
}
|
||||
|
||||
public void setSubtext(String text) {
|
||||
if (subtextView == null) {
|
||||
subtextView = new TextView(getContext());
|
||||
subtextView.setLines(1);
|
||||
subtextView.setSingleLine(true);
|
||||
subtextView.setGravity(Gravity.LEFT);
|
||||
subtextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
subtextView.setTextColor(0xff7C8286);
|
||||
subtextView.setVisibility(GONE);
|
||||
subtextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
|
||||
subtextView.setPadding(LocaleController.isRTL ? 0 : AndroidUtilities.dp(43), 0, LocaleController.isRTL ? AndroidUtilities.dp(43) : 0, 0);
|
||||
addView(subtextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL, 0, 10, 0, 0));
|
||||
}
|
||||
boolean visible = !TextUtils.isEmpty(text);
|
||||
boolean oldVisible = subtextView.getVisibility() == VISIBLE;
|
||||
if (visible != oldVisible) {
|
||||
subtextView.setVisibility(visible ? VISIBLE : GONE);
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) textView.getLayoutParams();
|
||||
layoutParams.bottomMargin = visible ? AndroidUtilities.dp(10) : 0;
|
||||
textView.setLayoutParams(layoutParams);
|
||||
}
|
||||
subtextView.setText(text);
|
||||
}
|
||||
|
||||
public TextView getTextView() {
|
||||
return textView;
|
||||
}
|
||||
|
||||
public ImageView getImageView() {
|
||||
return imageView;
|
||||
}
|
||||
|
||||
public void setSelectorColor(int selectorColor) {
|
||||
if (this.selectorColor != selectorColor) {
|
||||
this.selectorColor = selectorColor;
|
||||
|
|
|
@ -143,6 +143,8 @@ public class BottomSheet extends Dialog {
|
|||
protected String navBarColorKey = Theme.key_windowBackgroundGray;
|
||||
protected int navBarColor;
|
||||
|
||||
private OnDismissListener onHideListener;
|
||||
|
||||
public void setDisableScroll(boolean b) {
|
||||
disableScroll = b;
|
||||
}
|
||||
|
@ -725,7 +727,11 @@ public class BottomSheet extends Dialog {
|
|||
container.setOnApplyWindowInsetsListener((v, insets) -> {
|
||||
lastInsets = insets;
|
||||
v.requestLayout();
|
||||
return insets.consumeSystemWindowInsets();
|
||||
if (Build.VERSION.SDK_INT >= 30) {
|
||||
return WindowInsets.CONSUMED;
|
||||
} else {
|
||||
return insets.consumeSystemWindowInsets();
|
||||
}
|
||||
});
|
||||
container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
|
@ -738,6 +744,9 @@ public class BottomSheet extends Dialog {
|
|||
super.onCreate(savedInstanceState);
|
||||
|
||||
Window window = getWindow();
|
||||
/*if (Build.VERSION.SDK_INT >= 30) {
|
||||
window.setDecorFitsSystemWindows(true);
|
||||
}*/
|
||||
window.setWindowAnimations(R.style.DialogNoAnimation);
|
||||
setContentView(container, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
|
@ -998,6 +1007,10 @@ public class BottomSheet extends Dialog {
|
|||
}
|
||||
}
|
||||
|
||||
public void setOnHideListener(OnDismissListener listener) {
|
||||
onHideListener = listener;
|
||||
}
|
||||
|
||||
private void startOpenAnimation() {
|
||||
if (dismissed) {
|
||||
return;
|
||||
|
@ -1173,6 +1186,9 @@ public class BottomSheet extends Dialog {
|
|||
return;
|
||||
}
|
||||
dismissed = true;
|
||||
if (onHideListener != null) {
|
||||
onHideListener.onDismiss(this);
|
||||
}
|
||||
cancelSheetAnimation();
|
||||
if (!allowCustomAnimation || !onCustomCloseAnimation()) {
|
||||
currentSheetAnimationType = 2;
|
||||
|
|
|
@ -119,7 +119,11 @@ public class DrawerLayoutContainer extends FrameLayout {
|
|||
hasCutout = cutout != null && cutout.getBoundingRects().size() != 0;
|
||||
}
|
||||
invalidate();
|
||||
return insets.consumeSystemWindowInsets();
|
||||
if (Build.VERSION.SDK_INT >= 30) {
|
||||
return WindowInsets.CONSUMED;
|
||||
} else {
|
||||
return insets.consumeSystemWindowInsets();
|
||||
}
|
||||
});
|
||||
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
|
|
|
@ -2019,6 +2019,7 @@ public class Theme {
|
|||
public static Drawable dialogs_muteDrawable;
|
||||
public static Drawable dialogs_verifiedDrawable;
|
||||
public static ScamDrawable dialogs_scamDrawable;
|
||||
public static ScamDrawable dialogs_fakeDrawable;
|
||||
public static Drawable dialogs_verifiedCheckDrawable;
|
||||
public static Drawable dialogs_pinnedDrawable;
|
||||
public static Drawable dialogs_mentionDrawable;
|
||||
|
@ -5886,7 +5887,7 @@ public class Theme {
|
|||
}
|
||||
}
|
||||
|
||||
private static void applyDayNightThemeMaybe(boolean night) {
|
||||
public static void applyDayNightThemeMaybe(boolean night) {
|
||||
if (previousTheme != null) {
|
||||
return;
|
||||
}
|
||||
|
@ -6907,7 +6908,8 @@ public class Theme {
|
|||
dialogs_broadcastDrawable = resources.getDrawable(R.drawable.list_broadcast);
|
||||
dialogs_muteDrawable = resources.getDrawable(R.drawable.list_mute).mutate();
|
||||
dialogs_verifiedDrawable = resources.getDrawable(R.drawable.verified_area);
|
||||
dialogs_scamDrawable = new ScamDrawable(11);
|
||||
dialogs_scamDrawable = new ScamDrawable(11, 0);
|
||||
dialogs_fakeDrawable = new ScamDrawable(11, 1);
|
||||
dialogs_verifiedCheckDrawable = resources.getDrawable(R.drawable.verified_check);
|
||||
dialogs_mentionDrawable = resources.getDrawable(R.drawable.mentionchatslist);
|
||||
dialogs_botDrawable = resources.getDrawable(R.drawable.list_bot);
|
||||
|
@ -6969,6 +6971,7 @@ public class Theme {
|
|||
setDrawableColorByKey(dialogs_verifiedCheckDrawable, key_chats_verifiedCheck);
|
||||
setDrawableColorByKey(dialogs_holidayDrawable, key_actionBarDefaultTitle);
|
||||
setDrawableColorByKey(dialogs_scamDrawable, key_chats_draft);
|
||||
setDrawableColorByKey(dialogs_fakeDrawable, key_chats_draft);
|
||||
}
|
||||
|
||||
public static void destroyResources() {
|
||||
|
|
|
@ -30,6 +30,7 @@ import android.widget.TextView;
|
|||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.ui.Components.AudioPlayerAlert;
|
||||
import org.telegram.ui.Components.AvatarDrawable;
|
||||
import org.telegram.ui.Components.BackupImageView;
|
||||
import org.telegram.ui.Components.ChatBigEmptyView;
|
||||
|
@ -62,6 +63,8 @@ import java.util.HashMap;
|
|||
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
||||
public class ThemeDescription {
|
||||
|
||||
public static int FLAG_BACKGROUND = 0x00000001;
|
||||
|
@ -533,6 +536,13 @@ public class ThemeDescription {
|
|||
} else if ((changeFlags & FLAG_TEXTCOLOR) != 0) {
|
||||
if (child instanceof TextView) {
|
||||
((TextView) child).setTextColor(color);
|
||||
} else if (child instanceof AudioPlayerAlert.ClippingTextViewSwitcher) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? ((AudioPlayerAlert.ClippingTextViewSwitcher) child).getTextView() : ((AudioPlayerAlert.ClippingTextViewSwitcher) child).getNextTextView();
|
||||
if (textView != null) {
|
||||
textView.setTextColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((changeFlags & FLAG_SERVICEBACKGROUND) != 0) {
|
||||
Drawable background = child.getBackground();
|
||||
|
@ -710,6 +720,32 @@ public class ThemeDescription {
|
|||
} else {
|
||||
((SeekBarView) object).setInnerColor(color);
|
||||
}
|
||||
} else if (object instanceof AudioPlayerAlert.ClippingTextViewSwitcher) {
|
||||
if ((changeFlags & FLAG_FASTSCROLL) != 0) {
|
||||
for (int k = 0; k < 2; k++) {
|
||||
TextView textView = k == 0 ? ((AudioPlayerAlert.ClippingTextViewSwitcher) object).getTextView() : ((AudioPlayerAlert.ClippingTextViewSwitcher) object).getNextTextView();
|
||||
if (textView != null) {
|
||||
CharSequence text = textView.getText();
|
||||
if (text instanceof SpannedString) {
|
||||
TypefaceSpan[] spans = ((SpannedString) text).getSpans(0, text.length(), TypefaceSpan.class);
|
||||
if (spans != null && spans.length > 0) {
|
||||
for (int i = 0; i < spans.length; i++) {
|
||||
spans[i].setColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((changeFlags & FLAG_TEXTCOLOR) != 0) {
|
||||
if ((changeFlags & FLAG_CHECKTAG) == 0 || checkTag(currentKey, (View) object)) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? ((AudioPlayerAlert.ClippingTextViewSwitcher) object).getTextView() : ((AudioPlayerAlert.ClippingTextViewSwitcher) object).getNextTextView();
|
||||
if (textView != null) {
|
||||
textView.setTextColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,9 @@ package org.telegram.ui.Adapters;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
|
@ -27,13 +30,16 @@ import androidx.viewpager.widget.ViewPager;
|
|||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ContactsController;
|
||||
import org.telegram.messenger.DialogObject;
|
||||
import org.telegram.messenger.DownloadController;
|
||||
import org.telegram.messenger.Emoji;
|
||||
import org.telegram.messenger.FileLoader;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.ImageLocation;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.SharedConfig;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.messenger.Utilities;
|
||||
import org.telegram.tgnet.ConnectionsManager;
|
||||
import org.telegram.tgnet.TLObject;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
|
@ -44,10 +50,12 @@ import org.telegram.ui.Cells.DialogCell;
|
|||
import org.telegram.ui.Cells.DialogMeUrlCell;
|
||||
import org.telegram.ui.Cells.DialogsEmptyCell;
|
||||
import org.telegram.ui.Cells.HeaderCell;
|
||||
import org.telegram.ui.Cells.LoadingCell;
|
||||
import org.telegram.ui.Cells.ShadowSectionCell;
|
||||
import org.telegram.ui.Cells.TextCell;
|
||||
import org.telegram.ui.Cells.TextInfoPrivacyCell;
|
||||
import org.telegram.ui.Cells.UserCell;
|
||||
import org.telegram.ui.Components.CombinedDrawable;
|
||||
import org.telegram.ui.Components.FlickerLoadingView;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.PullForegroundDrawable;
|
||||
import org.telegram.ui.Components.RecyclerListView;
|
||||
|
@ -62,7 +70,9 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
private Context mContext;
|
||||
private ArchiveHintCell archiveHintCell;
|
||||
private ArrayList<TLRPC.TL_contact> onlineContacts;
|
||||
private int dialogsCount;
|
||||
private int prevContactsCount;
|
||||
private int prevDialogsCount;
|
||||
private int dialogsType;
|
||||
private int folderId;
|
||||
private long openedDialogId;
|
||||
|
@ -77,10 +87,19 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
private long lastSortTime;
|
||||
private PullForegroundDrawable pullForegroundDrawable;
|
||||
|
||||
private DialogsPreloader preloader;
|
||||
private Drawable arrowDrawable;
|
||||
|
||||
public DialogsAdapter(Context context, int type, int folder, boolean onlySelect, ArrayList<Long> selected, int account) {
|
||||
private ArrayList<TLRPC.Document> preloadedStickers = new ArrayList<>();
|
||||
private boolean preloadingSticker;
|
||||
|
||||
private DialogsPreloader preloader;
|
||||
private boolean forceShowEmptyCell;
|
||||
|
||||
private DialogsActivity parentFragment;
|
||||
|
||||
public DialogsAdapter(DialogsActivity fragment, Context context, int type, int folder, boolean onlySelect, ArrayList<Long> selected, int account) {
|
||||
mContext = context;
|
||||
parentFragment = fragment;
|
||||
dialogsType = type;
|
||||
folderId = folder;
|
||||
isOnlySelect = onlySelect;
|
||||
|
@ -114,6 +133,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
}
|
||||
if (showArchiveHint) {
|
||||
position -= 2;
|
||||
} else if (dialogsType == 11 || dialogsType == 13) {
|
||||
position -= 2;
|
||||
} else if (dialogsType == 12) {
|
||||
position -= 1;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
@ -128,11 +151,37 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void preloadGreetingsSticker() {
|
||||
if (preloadingSticker) {
|
||||
return;
|
||||
}
|
||||
preloadingSticker = true;
|
||||
TLRPC.TL_messages_getStickers req = new TLRPC.TL_messages_getStickers();
|
||||
req.emoticon = "\uD83D\uDC4B" + Emoji.fixEmoji("⭐");
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
|
||||
if (response instanceof TLRPC.TL_messages_stickers) {
|
||||
ArrayList<TLRPC.Document> list = ((TLRPC.TL_messages_stickers) response).stickers;
|
||||
if (!list.isEmpty()) {
|
||||
for (int a = 0; a < 5; a++) {
|
||||
TLRPC.Document sticker = list.get(Math.abs(Utilities.random.nextInt() % list.size()));
|
||||
AndroidUtilities.runOnUIThread(() -> FileLoader.getInstance(currentAccount).loadFile(ImageLocation.getForDocument(sticker), sticker, null, 0, 1));
|
||||
preloadedStickers.add(sticker);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public TLRPC.Document getPreloadedSticker() {
|
||||
return onlineContacts != null && !preloadedStickers.isEmpty() ? preloadedStickers.get(Utilities.random.nextInt(preloadedStickers.size())) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
ArrayList<TLRPC.Dialog> array = DialogsActivity.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen);
|
||||
int dialogsCount = array.size();
|
||||
if (dialogsType != 7 && dialogsType != 8 && dialogsCount == 0 && (folderId != 0 || MessagesController.getInstance(currentAccount).isLoadingDialogs(folderId) || !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId))) {
|
||||
MessagesController messagesController = MessagesController.getInstance(currentAccount);
|
||||
ArrayList<TLRPC.Dialog> array = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen);
|
||||
dialogsCount = array.size();
|
||||
if (!forceShowEmptyCell && dialogsType != 7 && dialogsType != 8 && dialogsType != 11 && dialogsCount == 0 && (folderId != 0 || messagesController.isLoadingDialogs(folderId) || !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId))) {
|
||||
onlineContacts = null;
|
||||
if (folderId == 1 && showArchiveHint) {
|
||||
return (currentCount = 2);
|
||||
|
@ -145,52 +194,76 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
count++;
|
||||
}
|
||||
} else {
|
||||
if (!MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId) || dialogsCount == 0) {
|
||||
if (!messagesController.isDialogsEndReached(folderId) || dialogsCount == 0) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
boolean hasContacts = false;
|
||||
if (hasHints) {
|
||||
count += 2 + MessagesController.getInstance(currentAccount).hintDialogs.size();
|
||||
} else if (dialogsType == 0 && dialogsCount == 0 && folderId == 0) {
|
||||
count += 2 + messagesController.hintDialogs.size();
|
||||
} else if (dialogsType == 0 && dialogsCount <= 10 && folderId == 0 && messagesController.isDialogsEndReached(folderId)) {
|
||||
if (ContactsController.getInstance(currentAccount).contacts.isEmpty() && ContactsController.getInstance(currentAccount).isLoadingContacts()) {
|
||||
onlineContacts = null;
|
||||
return (currentCount = 0);
|
||||
}
|
||||
|
||||
if (!ContactsController.getInstance(currentAccount).contacts.isEmpty()) {
|
||||
if (onlineContacts == null || prevContactsCount != ContactsController.getInstance(currentAccount).contacts.size()) {
|
||||
if (onlineContacts == null || prevDialogsCount != messagesController.dialogs_dict.size() || prevContactsCount != ContactsController.getInstance(currentAccount).contacts.size()) {
|
||||
onlineContacts = new ArrayList<>(ContactsController.getInstance(currentAccount).contacts);
|
||||
prevContactsCount = onlineContacts.size();
|
||||
prevDialogsCount = messagesController.dialogs_dict.size();
|
||||
int selfId = UserConfig.getInstance(currentAccount).clientUserId;
|
||||
for (int a = 0, N = onlineContacts.size(); a < N; a++) {
|
||||
if (onlineContacts.get(a).user_id == selfId) {
|
||||
int userId = onlineContacts.get(a).user_id;
|
||||
if (userId == selfId || messagesController.dialogs_dict.get(userId) != null) {
|
||||
onlineContacts.remove(a);
|
||||
break;
|
||||
a--;
|
||||
N--;
|
||||
}
|
||||
}
|
||||
if (onlineContacts.isEmpty()) {
|
||||
onlineContacts = null;
|
||||
}
|
||||
sortOnlineContacts(false);
|
||||
}
|
||||
count += onlineContacts.size() + 2;
|
||||
hasContacts = true;
|
||||
if (onlineContacts != null) {
|
||||
count += onlineContacts.size() + 2;
|
||||
hasContacts = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasContacts && onlineContacts != null) {
|
||||
onlineContacts = null;
|
||||
if (folderId == 0 && onlineContacts != null) {
|
||||
if (!hasContacts) {
|
||||
onlineContacts = null;
|
||||
} else {
|
||||
preloadGreetingsSticker();
|
||||
}
|
||||
}
|
||||
if (folderId == 1 && showArchiveHint) {
|
||||
count += 2;
|
||||
}
|
||||
if (folderId == 0 && dialogsCount != 0) {
|
||||
count++;
|
||||
if (dialogsCount > 10 && dialogsType == 0) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (dialogsType == 11 || dialogsType == 13) {
|
||||
count += 2;
|
||||
} else if (dialogsType == 12) {
|
||||
count += 1;
|
||||
}
|
||||
currentCount = count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public TLObject getItem(int i) {
|
||||
if (onlineContacts != null) {
|
||||
i -= 3;
|
||||
if (onlineContacts != null && (dialogsCount == 0 || i >= dialogsCount)) {
|
||||
if (dialogsCount == 0) {
|
||||
i -= 3;
|
||||
} else {
|
||||
i -= dialogsCount + 2;
|
||||
}
|
||||
if (i < 0 || i >= onlineContacts.size()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -198,8 +271,12 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
}
|
||||
if (showArchiveHint) {
|
||||
i -= 2;
|
||||
} else if (dialogsType == 11 || dialogsType == 13) {
|
||||
i -= 2;
|
||||
} else if (dialogsType == 12) {
|
||||
i -= 1;
|
||||
}
|
||||
ArrayList<TLRPC.Dialog> arrayList = DialogsActivity.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen);
|
||||
ArrayList<TLRPC.Dialog> arrayList = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen);
|
||||
if (hasHints) {
|
||||
int count = MessagesController.getInstance(currentAccount).hintDialogs.size();
|
||||
if (i < 2 + count) {
|
||||
|
@ -257,7 +334,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
return 0;
|
||||
} else if (status1 < 0 && status2 > 0 || status1 == 0 && status2 != 0) {
|
||||
return -1;
|
||||
} else if (status2 < 0 && status1 > 0 || status2 == 0 && status1 != 0) {
|
||||
} else if (status2 < 0 || status1 != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -299,7 +376,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
@Override
|
||||
public boolean isEnabled(RecyclerView.ViewHolder holder) {
|
||||
int viewType = holder.getItemViewType();
|
||||
return viewType != 1 && viewType != 5 && viewType != 3 && viewType != 8 && viewType != 7 && viewType != 9 && viewType != 10;
|
||||
return viewType != 1 && viewType != 5 && viewType != 3 && viewType != 8 && viewType != 7 && viewType != 9 && viewType != 10 && viewType != 11;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -307,13 +384,16 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
View view;
|
||||
switch (viewType) {
|
||||
case 0:
|
||||
DialogCell dialogCell = new DialogCell(mContext, true, false, currentAccount);
|
||||
DialogCell dialogCell = new DialogCell(parentFragment, mContext, true, false, currentAccount);
|
||||
dialogCell.setArchivedPullAnimation(pullForegroundDrawable);
|
||||
dialogCell.setPreloader(preloader);
|
||||
view = dialogCell;
|
||||
break;
|
||||
case 1:
|
||||
view = new LoadingCell(mContext);
|
||||
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(mContext);
|
||||
flickerLoadingView.setIsSingleCell(true);
|
||||
flickerLoadingView.setViewType(FlickerLoadingView.DIALOG_CELL_TYPE);
|
||||
view = flickerLoadingView;
|
||||
break;
|
||||
case 2: {
|
||||
HeaderCell headerCell = new HeaderCell(mContext);
|
||||
|
@ -359,17 +439,16 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
view = new UserCell(mContext, 8, 0, false);
|
||||
break;
|
||||
case 7:
|
||||
HeaderCell headerCell = new HeaderCell(mContext);
|
||||
headerCell.setText(LocaleController.getString("YourContacts", R.string.YourContacts));
|
||||
view = headerCell;
|
||||
view = new HeaderCell(mContext);
|
||||
break;
|
||||
case 8:
|
||||
case 8: {
|
||||
view = new ShadowSectionCell(mContext);
|
||||
Drawable drawable = Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow);
|
||||
CombinedDrawable combinedDrawable = new CombinedDrawable(new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray)), drawable);
|
||||
combinedDrawable.setFullsize(true);
|
||||
view.setBackgroundDrawable(combinedDrawable);
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
view = archiveHintCell;
|
||||
if (archiveHintCell.getParent() != null) {
|
||||
|
@ -377,12 +456,11 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
parent.removeView(archiveHintCell);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
default: {
|
||||
case 10: {
|
||||
view = new View(mContext) {
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int size = DialogsActivity.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen).size();
|
||||
int size = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen).size();
|
||||
boolean hasArchive = dialogsType == 0 && MessagesController.getInstance(currentAccount).dialogs_dict.get(DialogObject.makeFolderDialogId(1)) != null;
|
||||
View parent = (View) getParent();
|
||||
int height;
|
||||
|
@ -399,6 +477,9 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
}
|
||||
int cellHeight = AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 78 : 72);
|
||||
int dialogsHeight = size * cellHeight + (size - 1);
|
||||
if (onlineContacts != null) {
|
||||
dialogsHeight += onlineContacts.size() * AndroidUtilities.dp(58) + (onlineContacts.size() - 1) + AndroidUtilities.dp(52);
|
||||
}
|
||||
int archiveHeight = (hasArchive ? cellHeight + 1 : 0);
|
||||
if (dialogsHeight < height) {
|
||||
height = height - dialogsHeight + archiveHeight;
|
||||
|
@ -423,6 +504,65 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
case 11: {
|
||||
view = new TextInfoPrivacyCell(mContext) {
|
||||
|
||||
private int movement;
|
||||
private float moveProgress;
|
||||
private long lastUpdateTime;
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
@Override
|
||||
protected void onTextDraw() {
|
||||
if (arrowDrawable != null) {
|
||||
Rect bounds = arrowDrawable.getBounds();
|
||||
int dx = (int) (moveProgress * AndroidUtilities.dp(3));
|
||||
arrowDrawable.setBounds(x + dx, y + AndroidUtilities.dp(1), x + dx + bounds.width(), y + AndroidUtilities.dp(1) + bounds.height());
|
||||
|
||||
long newUpdateTime = SystemClock.elapsedRealtime();
|
||||
long dt = newUpdateTime - lastUpdateTime;
|
||||
if (dt > 17) {
|
||||
dt = 17;
|
||||
}
|
||||
lastUpdateTime = newUpdateTime;
|
||||
if (movement == 0) {
|
||||
moveProgress += dt / 664.0f;
|
||||
if (moveProgress >= 1.0f) {
|
||||
movement = 1;
|
||||
moveProgress = 1.0f;
|
||||
}
|
||||
} else {
|
||||
moveProgress -= dt / 664.0f;
|
||||
if (moveProgress <= 0.0f) {
|
||||
movement = 0;
|
||||
moveProgress = 0.0f;
|
||||
}
|
||||
}
|
||||
getTextView().invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
if (arrowDrawable != null) {
|
||||
x = arrowDrawable.getBounds().left;
|
||||
y = arrowDrawable.getBounds().top;
|
||||
}
|
||||
}
|
||||
};
|
||||
Drawable drawable = Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow);
|
||||
CombinedDrawable combinedDrawable = new CombinedDrawable(new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray)), drawable);
|
||||
combinedDrawable.setFullsize(true);
|
||||
view.setBackgroundDrawable(combinedDrawable);
|
||||
break;
|
||||
}
|
||||
case 12:
|
||||
default: {
|
||||
view = new TextCell(mContext);
|
||||
}
|
||||
}
|
||||
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, viewType == 5 ? RecyclerView.LayoutParams.MATCH_PARENT : RecyclerView.LayoutParams.WRAP_CONTENT));
|
||||
|
@ -436,11 +576,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
DialogCell cell = (DialogCell) holder.itemView;
|
||||
TLRPC.Dialog dialog = (TLRPC.Dialog) getItem(i);
|
||||
TLRPC.Dialog nextDialog = (TLRPC.Dialog) getItem(i + 1);
|
||||
if (folderId == 0) {
|
||||
cell.useSeparator = (i != getItemCount() - 2);
|
||||
} else {
|
||||
cell.useSeparator = (i != getItemCount() - 1);
|
||||
}
|
||||
cell.useSeparator = nextDialog != null;
|
||||
cell.fullSeparator = dialog.pinned && nextDialog != null && !nextDialog.pinned;
|
||||
if (dialogsType == 0) {
|
||||
if (AndroidUtilities.isTablet()) {
|
||||
|
@ -474,25 +610,76 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
}
|
||||
case 6: {
|
||||
UserCell cell = (UserCell) holder.itemView;
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(onlineContacts.get(i - 3).user_id);
|
||||
int position;
|
||||
if (dialogsCount == 0) {
|
||||
position = i - 3;
|
||||
} else {
|
||||
position = i - dialogsCount - 2;
|
||||
}
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(onlineContacts.get(position).user_id);
|
||||
cell.setData(user, null, null, 0);
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
HeaderCell cell = (HeaderCell) holder.itemView;
|
||||
if (dialogsType == 11 || dialogsType == 12 || dialogsType == 13) {
|
||||
if (i == 0) {
|
||||
cell.setText(LocaleController.getString("ImportHeader", R.string.ImportHeader));
|
||||
} else {
|
||||
cell.setText(LocaleController.getString("ImportHeaderContacts", R.string.ImportHeaderContacts));
|
||||
}
|
||||
} else {
|
||||
cell.setText(LocaleController.getString("YourContacts", R.string.YourContacts));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 11: {
|
||||
TextInfoPrivacyCell cell = (TextInfoPrivacyCell) holder.itemView;
|
||||
cell.setText(LocaleController.getString("TapOnThePencil", R.string.TapOnThePencil));
|
||||
if (arrowDrawable == null) {
|
||||
arrowDrawable = mContext.getResources().getDrawable(R.drawable.arrow_newchat);
|
||||
arrowDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText4), PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
TextView textView = cell.getTextView();
|
||||
textView.setCompoundDrawablePadding(AndroidUtilities.dp(4));
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(null, null, arrowDrawable, null);
|
||||
textView.getLayoutParams().width = LayoutHelper.WRAP_CONTENT;
|
||||
break;
|
||||
}
|
||||
case 12: {
|
||||
TextCell cell = (TextCell) holder.itemView;
|
||||
cell.setColors(Theme.key_windowBackgroundWhiteBlueText4, Theme.key_windowBackgroundWhiteBlueText4);
|
||||
cell.setTextAndIcon(LocaleController.getString("CreateGroupForImport", R.string.CreateGroupForImport), R.drawable.groups_create, dialogsCount != 0);
|
||||
cell.setIsInDialogs();
|
||||
cell.setOffsetFromImage(75);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int i) {
|
||||
if (onlineContacts != null) {
|
||||
if (i == 0) {
|
||||
return 5;
|
||||
} else if (i == 1) {
|
||||
return 8;
|
||||
} else if (i == 2) {
|
||||
return 7;
|
||||
if (dialogsCount == 0) {
|
||||
if (i == 0) {
|
||||
return 5;
|
||||
} else if (i == 1) {
|
||||
return 8;
|
||||
} else if (i == 2) {
|
||||
return 7;
|
||||
}
|
||||
} else {
|
||||
return 6;
|
||||
if (i < dialogsCount) {
|
||||
return 0;
|
||||
} else if (i == dialogsCount) {
|
||||
return 8;
|
||||
} else if (i == dialogsCount + 1) {
|
||||
return 7;
|
||||
} else if (i == currentCount - 1) {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
return 6;
|
||||
} else if (hasHints) {
|
||||
int count = MessagesController.getInstance(currentAccount).hintDialogs.size();
|
||||
if (i < 2 + count) {
|
||||
|
@ -513,10 +700,27 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
} else {
|
||||
i -= 2;
|
||||
}
|
||||
} else if (dialogsType == 11 || dialogsType == 13) {
|
||||
if (i == 0) {
|
||||
return 7;
|
||||
} else if (i == 1) {
|
||||
return 12;
|
||||
} else {
|
||||
i -= 2;
|
||||
}
|
||||
} else if (dialogsType == 12) {
|
||||
if (i == 0) {
|
||||
return 7;
|
||||
} else {
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
int size = DialogsActivity.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen).size();
|
||||
if (folderId == 0 && dialogsCount > 10 && i == currentCount - 2 && dialogsType == 0) {
|
||||
return 11;
|
||||
}
|
||||
int size = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen).size();
|
||||
if (i == size) {
|
||||
if (dialogsType != 7 && dialogsType != 8 && !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) {
|
||||
if (!forceShowEmptyCell && dialogsType != 7 && dialogsType != 8 && !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) {
|
||||
return 1;
|
||||
} else if (size == 0) {
|
||||
return 5;
|
||||
|
@ -531,7 +735,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
|
||||
@Override
|
||||
public void notifyItemMoved(int fromPosition, int toPosition) {
|
||||
ArrayList<TLRPC.Dialog> dialogs = DialogsActivity.getDialogsArray(currentAccount, dialogsType, folderId, false);
|
||||
ArrayList<TLRPC.Dialog> dialogs = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, false);
|
||||
int fromIndex = fixPosition(fromPosition);
|
||||
int toIndex = fixPosition(toPosition);
|
||||
TLRPC.Dialog fromDialog = dialogs.get(fromIndex);
|
||||
|
@ -682,4 +886,12 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter {
|
|||
resumed = false;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentCount() {
|
||||
return currentCount;
|
||||
}
|
||||
|
||||
public void setForceShowEmptyCell(boolean forceShowEmptyCell) {
|
||||
this.forceShowEmptyCell = forceShowEmptyCell;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
private ArrayList<FiltersView.DateData> localTipDates = new ArrayList<>();
|
||||
private FilteredSearchView.Delegate filtersDelegate;
|
||||
private int folderId;
|
||||
private int currentItemCount;
|
||||
|
||||
public boolean isSearching() {
|
||||
return waitingResponseCount > 0;
|
||||
|
@ -358,11 +359,11 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
}
|
||||
|
||||
public boolean hasRecentSearch() {
|
||||
return dialogsType != 2 && dialogsType != 4 && dialogsType != 5 && dialogsType != 6 && (!recentSearchObjects.isEmpty() || !MediaDataController.getInstance(currentAccount).hints.isEmpty());
|
||||
return dialogsType != 2 && dialogsType != 4 && dialogsType != 5 && dialogsType != 6 && dialogsType != 11 && (!recentSearchObjects.isEmpty() || !MediaDataController.getInstance(currentAccount).hints.isEmpty());
|
||||
}
|
||||
|
||||
public boolean isRecentSearchDisplayed() {
|
||||
return needMessagesSearch != 2 && !searchWas && (!recentSearchObjects.isEmpty() || !MediaDataController.getInstance(currentAccount).hints.isEmpty()) && dialogsType != 2 && dialogsType != 4 && dialogsType != 5 && dialogsType != 6;
|
||||
return needMessagesSearch != 2 && !searchWas && (!recentSearchObjects.isEmpty() || !MediaDataController.getInstance(currentAccount).hints.isEmpty()) && dialogsType != 2 && dialogsType != 4 && dialogsType != 5 && dialogsType != 6 && dialogsType != 11;
|
||||
}
|
||||
|
||||
public void loadRecentSearch() {
|
||||
|
@ -646,7 +647,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
searchResultNames.clear();
|
||||
searchResultHashtags.clear();
|
||||
searchAdapterHelper.mergeResults(null);
|
||||
searchAdapterHelper.queryServerSearch(null, true, true, true, true, dialogsType == 2, 0, dialogsType == 0, 0, 0);
|
||||
searchAdapterHelper.queryServerSearch(null, true, true, dialogsType != 11, dialogsType != 11, dialogsType == 2 || dialogsType == 11, 0, dialogsType == 0, 0, 0);
|
||||
searchWas = false;
|
||||
lastSearchId = 0;
|
||||
waitingResponseCount = 0;
|
||||
|
@ -695,7 +696,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
return;
|
||||
}
|
||||
if (needMessagesSearch != 2) {
|
||||
searchAdapterHelper.queryServerSearch(query, true, dialogsType != 4, true, dialogsType != 4, dialogsType == 2, 0, dialogsType == 0, 0, searchId);
|
||||
searchAdapterHelper.queryServerSearch(query, true, dialogsType != 4, true, dialogsType != 4 && dialogsType != 11, dialogsType == 2 || dialogsType == 1, 0, dialogsType == 0, 0, searchId);
|
||||
} else {
|
||||
waitingResponseCount -= 2;
|
||||
}
|
||||
|
@ -737,7 +738,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
if (messagesCount != 0) {
|
||||
count += messagesCount + 1 + (messagesSearchEndReached ? 0 : 1);
|
||||
}
|
||||
return count;
|
||||
return currentItemCount = count;
|
||||
}
|
||||
|
||||
public Object getItem(int i) {
|
||||
|
@ -865,7 +866,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
view = new GraySectionCell(mContext);
|
||||
break;
|
||||
case 2:
|
||||
view = new DialogCell(mContext, false, true);
|
||||
view = new DialogCell(null, mContext, false, true);
|
||||
break;
|
||||
case 3:
|
||||
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(mContext);
|
||||
|
@ -1181,4 +1182,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
filtersDelegate.updateFiltersView(false, null, localTipDates);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentItemCount() {
|
||||
return currentItemCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public class MessagesSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
View view = null;
|
||||
switch (viewType) {
|
||||
case 0:
|
||||
view = new DialogCell(mContext, false, true);
|
||||
view = new DialogCell(null, mContext, false, true);
|
||||
break;
|
||||
case 1:
|
||||
view = new LoadingCell(mContext);
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.telegram.messenger.MediaDataController;
|
|||
import org.telegram.messenger.Emoji;
|
||||
import org.telegram.messenger.ImageLocation;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.SharedConfig;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
|
@ -90,7 +91,7 @@ public class StickersAdapter extends RecyclerListView.SelectionAdapter implement
|
|||
String fileName = (String) args[0];
|
||||
stickersToLoad.remove(fileName);
|
||||
if (stickersToLoad.isEmpty()) {
|
||||
boolean show = stickers != null && !stickers.isEmpty() && stickersToLoad.isEmpty();
|
||||
boolean show = stickers != null && !stickers.isEmpty();
|
||||
if (show) {
|
||||
keywordResults = null;
|
||||
}
|
||||
|
@ -269,73 +270,76 @@ public class StickersAdapter extends RecyclerListView.SelectionAdapter implement
|
|||
ConnectionsManager.getInstance(currentAccount).cancelRequest(lastReqId, true);
|
||||
lastReqId = 0;
|
||||
}
|
||||
boolean serverStickersOnly = MessagesController.getInstance(currentAccount).suggestStickersApiOnly;
|
||||
|
||||
delayLocalResults = false;
|
||||
final ArrayList<TLRPC.Document> recentStickers = MediaDataController.getInstance(currentAccount).getRecentStickersNoCopy(MediaDataController.TYPE_IMAGE);
|
||||
final ArrayList<TLRPC.Document> favsStickers = MediaDataController.getInstance(currentAccount).getRecentStickersNoCopy(MediaDataController.TYPE_FAVE);
|
||||
int recentsAdded = 0;
|
||||
for (int a = 0, size = Math.min(20, recentStickers.size()); a < size; a++) {
|
||||
TLRPC.Document document = recentStickers.get(a);
|
||||
if (isValidSticker(document, lastSticker)) {
|
||||
addStickerToResult(document, "recent");
|
||||
recentsAdded++;
|
||||
if (recentsAdded >= 5) {
|
||||
break;
|
||||
if (!serverStickersOnly) {
|
||||
final ArrayList<TLRPC.Document> recentStickers = MediaDataController.getInstance(currentAccount).getRecentStickersNoCopy(MediaDataController.TYPE_IMAGE);
|
||||
final ArrayList<TLRPC.Document> favsStickers = MediaDataController.getInstance(currentAccount).getRecentStickersNoCopy(MediaDataController.TYPE_FAVE);
|
||||
int recentsAdded = 0;
|
||||
for (int a = 0, size = Math.min(20, recentStickers.size()); a < size; a++) {
|
||||
TLRPC.Document document = recentStickers.get(a);
|
||||
if (isValidSticker(document, lastSticker)) {
|
||||
addStickerToResult(document, "recent");
|
||||
recentsAdded++;
|
||||
if (recentsAdded >= 5) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int a = 0, size = favsStickers.size(); a < size; a++) {
|
||||
TLRPC.Document document = favsStickers.get(a);
|
||||
if (isValidSticker(document, lastSticker)) {
|
||||
addStickerToResult(document, "fav");
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<String, ArrayList<TLRPC.Document>> allStickers = MediaDataController.getInstance(currentAccount).getAllStickers();
|
||||
ArrayList<TLRPC.Document> newStickers = allStickers != null ? allStickers.get(lastSticker) : null;
|
||||
if (newStickers != null && !newStickers.isEmpty()) {
|
||||
addStickersToResult(newStickers, null);
|
||||
}
|
||||
if (stickers != null) {
|
||||
Collections.sort(stickers, new Comparator<StickerResult>() {
|
||||
private int getIndex(StickerResult result) {
|
||||
for (int a = 0; a < favsStickers.size(); a++) {
|
||||
if (favsStickers.get(a).id == result.sticker.id) {
|
||||
return a + 2000000;
|
||||
}
|
||||
}
|
||||
for (int a = 0; a < Math.min(20, recentStickers.size()); a++) {
|
||||
if (recentStickers.get(a).id == result.sticker.id) {
|
||||
return recentStickers.size() - a + 1000000;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
for (int a = 0, size = favsStickers.size(); a < size; a++) {
|
||||
TLRPC.Document document = favsStickers.get(a);
|
||||
if (isValidSticker(document, lastSticker)) {
|
||||
addStickerToResult(document, "fav");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(StickerResult lhs, StickerResult rhs) {
|
||||
boolean isAnimated1 = MessageObject.isAnimatedStickerDocument(lhs.sticker, true);
|
||||
boolean isAnimated2 = MessageObject.isAnimatedStickerDocument(rhs.sticker, true);
|
||||
if (isAnimated1 == isAnimated2) {
|
||||
int idx1 = getIndex(lhs);
|
||||
int idx2 = getIndex(rhs);
|
||||
if (idx1 > idx2) {
|
||||
return -1;
|
||||
} else if (idx1 < idx2) {
|
||||
return 1;
|
||||
HashMap<String, ArrayList<TLRPC.Document>> allStickers = MediaDataController.getInstance(currentAccount).getAllStickers();
|
||||
ArrayList<TLRPC.Document> newStickers = allStickers != null ? allStickers.get(lastSticker) : null;
|
||||
if (newStickers != null && !newStickers.isEmpty()) {
|
||||
addStickersToResult(newStickers, null);
|
||||
}
|
||||
if (stickers != null) {
|
||||
Collections.sort(stickers, new Comparator<StickerResult>() {
|
||||
private int getIndex(StickerResult result) {
|
||||
for (int a = 0; a < favsStickers.size(); a++) {
|
||||
if (favsStickers.get(a).id == result.sticker.id) {
|
||||
return a + 2000000;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
if (isAnimated1 && !isAnimated2) {
|
||||
return -1;
|
||||
for (int a = 0; a < Math.min(20, recentStickers.size()); a++) {
|
||||
if (recentStickers.get(a).id == result.sticker.id) {
|
||||
return recentStickers.size() - a + 1000000;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(StickerResult lhs, StickerResult rhs) {
|
||||
boolean isAnimated1 = MessageObject.isAnimatedStickerDocument(lhs.sticker, true);
|
||||
boolean isAnimated2 = MessageObject.isAnimatedStickerDocument(rhs.sticker, true);
|
||||
if (isAnimated1 == isAnimated2) {
|
||||
int idx1 = getIndex(lhs);
|
||||
int idx2 = getIndex(rhs);
|
||||
if (idx1 > idx2) {
|
||||
return -1;
|
||||
} else if (idx1 < idx2) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
if (isAnimated1) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if (SharedConfig.suggestStickers == 0) {
|
||||
if (SharedConfig.suggestStickers == 0 || serverStickersOnly) {
|
||||
searchServerStickers(lastSticker, originalEmoji);
|
||||
}
|
||||
|
||||
|
|
|
@ -155,28 +155,25 @@ public class StickersSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
MediaDataController.getInstance(currentAccount).fetchNewEmojiKeywords(newLanguage);
|
||||
}
|
||||
delegate.setLastSearchKeyboardLanguage(newLanguage);
|
||||
MediaDataController.getInstance(currentAccount).getEmojiSuggestions(delegate.getLastSearchKeyboardLanguage(), searchQuery, false, new MediaDataController.KeywordResultCallback() {
|
||||
@Override
|
||||
public void run(ArrayList<MediaDataController.KeywordResult> param, String alias) {
|
||||
if (lastId != emojiSearchId) {
|
||||
return;
|
||||
}
|
||||
boolean added = false;
|
||||
for (int a = 0, size = param.size(); a < size; a++) {
|
||||
String emoji = param.get(a).emoji;
|
||||
ArrayList<TLRPC.Document> newStickers = allStickers != null ? allStickers.get(emoji) : null;
|
||||
if (newStickers != null && !newStickers.isEmpty()) {
|
||||
clear();
|
||||
if (!emojiStickers.containsKey(newStickers)) {
|
||||
emojiStickers.put(newStickers, emoji);
|
||||
emojiArrays.add(newStickers);
|
||||
added = true;
|
||||
}
|
||||
MediaDataController.getInstance(currentAccount).getEmojiSuggestions(delegate.getLastSearchKeyboardLanguage(), searchQuery, false, (param, alias) -> {
|
||||
if (lastId != emojiSearchId) {
|
||||
return;
|
||||
}
|
||||
boolean added = false;
|
||||
for (int a = 0, size = param.size(); a < size; a++) {
|
||||
String emoji = param.get(a).emoji;
|
||||
ArrayList<TLRPC.Document> newStickers = allStickers != null ? allStickers.get(emoji) : null;
|
||||
if (newStickers != null && !newStickers.isEmpty()) {
|
||||
clear();
|
||||
if (!emojiStickers.containsKey(newStickers)) {
|
||||
emojiStickers.put(newStickers, emoji);
|
||||
emojiArrays.add(newStickers);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
if (added) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
if (added) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -400,7 +397,6 @@ public class StickersSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
return new RecyclerListView.Holder(view);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
|
@ -449,8 +445,6 @@ public class StickersSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
if (holder.getItemViewType() == 3) {
|
||||
bindFeaturedStickerSetInfoCell((FeaturedStickerSetInfoCell) holder.itemView, position, true);
|
||||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position, payloads);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,7 +539,6 @@ public class StickersSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
installing = false;
|
||||
} else if (removing && !cell.isInstalled()) {
|
||||
removingStickerSets.remove(stickerSetCovered.set.id);
|
||||
removing = false;
|
||||
}
|
||||
}
|
||||
cell.setAddDrawProgress(!forceInstalled && installing, animated);
|
||||
|
@ -601,7 +594,7 @@ public class StickersSearchAdapter extends RecyclerListView.SelectionAdapter {
|
|||
}
|
||||
}
|
||||
int count = (int) Math.ceil(documentsCount / (float) delegate.getStickersPerRow());
|
||||
for (int b = 0, N = count; b < N; b++) {
|
||||
for (int b = 0; b < count; b++) {
|
||||
rowStartPack.put(startRow + b, documentsCount);
|
||||
}
|
||||
totalItems += count * delegate.getStickersPerRow();
|
||||
|
|
|
@ -3033,7 +3033,13 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
|
|||
//containerView.setFitsSystemWindows(true);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
windowView.setFitsSystemWindows(true);
|
||||
containerView.setOnApplyWindowInsetsListener((v, insets) -> insets.consumeSystemWindowInsets());
|
||||
containerView.setOnApplyWindowInsetsListener((v, insets) -> {
|
||||
if (Build.VERSION.SDK_INT >= 30) {
|
||||
return WindowInsets.CONSUMED;
|
||||
} else {
|
||||
return insets.consumeSystemWindowInsets();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fullscreenVideoContainer = new FrameLayout(activity);
|
||||
|
|
|
@ -299,6 +299,10 @@ public class BubbleActivity extends Activity implements ActionBarLayout.ActionBa
|
|||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mainFragmentsStack.size() == 1) {
|
||||
super.onBackPressed();
|
||||
return;
|
||||
}
|
||||
if (passcodeView.getVisibility() == View.VISIBLE) {
|
||||
finish();
|
||||
return;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package org.telegram.ui;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.StateListAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Paint;
|
||||
|
@ -19,9 +23,11 @@ import android.view.Gravity;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
|
@ -33,23 +39,29 @@ import org.telegram.messenger.UserConfig;
|
|||
import org.telegram.tgnet.ConnectionsManager;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.ActionBar;
|
||||
import org.telegram.ui.ActionBar.ActionBarMenu;
|
||||
import org.telegram.ui.ActionBar.ActionBarMenuItem;
|
||||
import org.telegram.ui.ActionBar.AlertDialog;
|
||||
import org.telegram.ui.ActionBar.BackDrawable;
|
||||
import org.telegram.ui.ActionBar.BaseFragment;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.ActionBar.ThemeDescription;
|
||||
import org.telegram.ui.Cells.CheckBoxCell;
|
||||
import org.telegram.ui.Cells.LoadingCell;
|
||||
import org.telegram.ui.Cells.LocationCell;
|
||||
import org.telegram.ui.Cells.ProfileSearchCell;
|
||||
import org.telegram.ui.Cells.TextInfoPrivacyCell;
|
||||
import org.telegram.ui.Components.CheckBox2;
|
||||
import org.telegram.ui.Components.CombinedDrawable;
|
||||
import org.telegram.ui.Components.EmptyTextProgressView;
|
||||
import org.telegram.ui.Components.FlickerLoadingView;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.NumberTextView;
|
||||
import org.telegram.ui.Components.RecyclerListView;
|
||||
import org.telegram.ui.Components.voip.VoIPHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
@ -61,12 +73,20 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
private LinearLayoutManager layoutManager;
|
||||
private RecyclerListView listView;
|
||||
private ImageView floatingButton;
|
||||
private FlickerLoadingView flickerLoadingView;
|
||||
|
||||
private NumberTextView selectedDialogsCountTextView;
|
||||
private ArrayList<View> actionModeViews = new ArrayList<>();
|
||||
|
||||
private ActionBarMenuItem otherItem;
|
||||
|
||||
private ArrayList<CallLogRow> calls = new ArrayList<>();
|
||||
private boolean loading;
|
||||
private boolean firstLoaded;
|
||||
private boolean endReached;
|
||||
|
||||
private ArrayList<Integer> selectedIds = new ArrayList<>();
|
||||
|
||||
private int prevPosition;
|
||||
private int prevTop;
|
||||
private boolean scrollUpdated;
|
||||
|
@ -79,10 +99,15 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
private ImageSpan iconOut, iconIn, iconMissed;
|
||||
private TLRPC.User lastCallUser;
|
||||
|
||||
private boolean openTransitionStarted;
|
||||
|
||||
private static final int TYPE_OUT = 0;
|
||||
private static final int TYPE_IN = 1;
|
||||
private static final int TYPE_MISSED = 2;
|
||||
|
||||
private static final int delete_all_calls = 1;
|
||||
private static final int delete = 2;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void didReceivedNotification(int id, int account, Object... args) {
|
||||
|
@ -119,6 +144,9 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
listViewAdapter.notifyItemInserted(0);
|
||||
}
|
||||
}
|
||||
if (otherItem != null) {
|
||||
otherItem.setVisibility(calls.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
} else if (id == NotificationCenter.messagesDeleted && firstLoaded) {
|
||||
boolean scheduled = (Boolean) args[2];
|
||||
if (scheduled) {
|
||||
|
@ -140,8 +168,9 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
if (row.calls.size() == 0)
|
||||
itrtr.remove();
|
||||
}
|
||||
if (didChange && listViewAdapter != null)
|
||||
if (didChange && listViewAdapter != null) {
|
||||
listViewAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,6 +178,7 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
|
||||
private ImageView imageView;
|
||||
private ProfileSearchCell profileSearchCell;
|
||||
private CheckBox2 checkBox;
|
||||
|
||||
public CustomCell(Context context) {
|
||||
super(context);
|
||||
|
@ -168,6 +198,19 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
imageView.setOnClickListener(callBtnClickListener);
|
||||
imageView.setContentDescription(LocaleController.getString("Call", R.string.Call));
|
||||
addView(imageView, LayoutHelper.createFrame(48, 48, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 8, 0, 8, 0));
|
||||
|
||||
checkBox = new CheckBox2(context, 21);
|
||||
checkBox.setColor(null, Theme.key_windowBackgroundWhite, Theme.key_checkboxCheck);
|
||||
checkBox.setDrawUnchecked(false);
|
||||
checkBox.setDrawBackgroundAsArc(3);
|
||||
addView(checkBox, LayoutHelper.createFrame(24, 24, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 42, 32, 42, 0));
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked, boolean animated) {
|
||||
if (checkBox == null) {
|
||||
return;
|
||||
}
|
||||
checkBox.setChecked(checked, animated);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,23 +256,40 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
redDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_calls_callReceivedRedIcon), PorterDuff.Mode.MULTIPLY));
|
||||
iconMissed = new ImageSpan(redDrawable, ImageSpan.ALIGN_BOTTOM);
|
||||
|
||||
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
|
||||
actionBar.setBackButtonDrawable(new BackDrawable(false));
|
||||
actionBar.setAllowOverlayTitle(true);
|
||||
actionBar.setTitle(LocaleController.getString("Calls", R.string.Calls));
|
||||
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
|
||||
@Override
|
||||
public void onItemClick(int id) {
|
||||
if (id == -1) {
|
||||
finishFragment();
|
||||
if (actionBar.isActionModeShowed()) {
|
||||
hideActionMode(true);
|
||||
} else {
|
||||
finishFragment();
|
||||
}
|
||||
} else if (id == delete_all_calls) {
|
||||
showDeleteAlert(true);
|
||||
} else if (id == delete) {
|
||||
showDeleteAlert(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ActionBarMenu menu = actionBar.createMenu();
|
||||
otherItem = menu.addItem(10, R.drawable.ic_ab_other);
|
||||
otherItem.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions));
|
||||
otherItem.addSubItem(delete_all_calls, R.drawable.msg_delete, LocaleController.getString("DeleteAllCalls", R.string.DeleteAllCalls));
|
||||
|
||||
fragmentView = new FrameLayout(context);
|
||||
fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
FrameLayout frameLayout = (FrameLayout) fragmentView;
|
||||
|
||||
emptyView = new EmptyTextProgressView(context);
|
||||
flickerLoadingView = new FlickerLoadingView(context);
|
||||
flickerLoadingView.setViewType(FlickerLoadingView.CALL_LOG_TYPE);
|
||||
flickerLoadingView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
|
||||
flickerLoadingView.showDate(false);
|
||||
emptyView = new EmptyTextProgressView(context, flickerLoadingView);
|
||||
emptyView.setText(LocaleController.getString("NoCallLog", R.string.NoCallLog));
|
||||
frameLayout.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
|
||||
|
@ -245,35 +305,21 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
return;
|
||||
}
|
||||
CallLogRow row = calls.get(position);
|
||||
Bundle args = new Bundle();
|
||||
args.putInt("user_id", row.user.id);
|
||||
args.putInt("message_id", row.calls.get(0).id);
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats);
|
||||
presentFragment(new ChatActivity(args), true);
|
||||
if (actionBar.isActionModeShowed()) {
|
||||
addOrRemoveSelectedDialog(row.calls, (CustomCell) view);
|
||||
} else {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt("user_id", row.user.id);
|
||||
args.putInt("message_id", row.calls.get(0).id);
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats);
|
||||
presentFragment(new ChatActivity(args), true);
|
||||
}
|
||||
});
|
||||
listView.setOnItemLongClickListener((view, position) -> {
|
||||
if (position < 0 || position >= calls.size()) {
|
||||
return false;
|
||||
}
|
||||
final CallLogRow row = calls.get(position);
|
||||
ArrayList<String> items = new ArrayList<>();
|
||||
items.add(LocaleController.getString("Delete", R.string.Delete));
|
||||
if (VoIPHelper.canRateCall((TLRPC.TL_messageActionPhoneCall) row.calls.get(0).action)) {
|
||||
items.add(LocaleController.getString("CallMessageReportProblem", R.string.CallMessageReportProblem));
|
||||
}
|
||||
new AlertDialog.Builder(getParentActivity())
|
||||
.setTitle(LocaleController.getString("Calls", R.string.Calls))
|
||||
.setItems(items.toArray(new String[0]), (dialog, which) -> {
|
||||
switch (which) {
|
||||
case 0:
|
||||
confirmAndDelete(row);
|
||||
break;
|
||||
case 1:
|
||||
VoIPHelper.showRateAlert(getParentActivity(), (TLRPC.TL_messageActionPhoneCall) row.calls.get(0).action);
|
||||
break;
|
||||
}
|
||||
})
|
||||
.show();
|
||||
addOrRemoveSelectedDialog(calls.get(position).calls, (CustomCell) view);
|
||||
return true;
|
||||
});
|
||||
listView.setOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
|
@ -320,7 +366,6 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
emptyView.showTextView();
|
||||
}
|
||||
|
||||
|
||||
floatingButton = new ImageView(context);
|
||||
floatingButton.setVisibility(View.VISIBLE);
|
||||
floatingButton.setScaleType(ImageView.ScaleType.CENTER);
|
||||
|
@ -368,6 +413,156 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
return fragmentView;
|
||||
}
|
||||
|
||||
private void showDeleteAlert(boolean all) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
||||
|
||||
if (all) {
|
||||
builder.setTitle(LocaleController.getString("DeleteAllCalls", R.string.DeleteAllCalls));
|
||||
builder.setMessage(LocaleController.getString("DeleteAllCallsText", R.string.DeleteAllCallsText));
|
||||
} else {
|
||||
builder.setTitle(LocaleController.getString("DeleteCalls", R.string.DeleteCalls));
|
||||
builder.setMessage(LocaleController.getString("DeleteSelectedCallsText", R.string.DeleteSelectedCallsText));
|
||||
}
|
||||
final boolean[] checks = new boolean[]{false};
|
||||
FrameLayout frameLayout = new FrameLayout(getParentActivity());
|
||||
CheckBoxCell cell = new CheckBoxCell(getParentActivity(), 1);
|
||||
cell.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
cell.setText(LocaleController.getString("DeleteCallsForEveryone", R.string.DeleteCallsForEveryone), "", false, false);
|
||||
cell.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(8) : 0, 0, LocaleController.isRTL ? 0 : AndroidUtilities.dp(8), 0);
|
||||
frameLayout.addView(cell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.TOP | Gravity.LEFT, 8, 0, 8, 0));
|
||||
cell.setOnClickListener(v -> {
|
||||
CheckBoxCell cell1 = (CheckBoxCell) v;
|
||||
checks[0] = !checks[0];
|
||||
cell1.setChecked(checks[0], true);
|
||||
});
|
||||
builder.setView(frameLayout);
|
||||
builder.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), (dialogInterface, i) -> {
|
||||
if (all) {
|
||||
deleteAllMessages(checks[0]);
|
||||
calls.clear();
|
||||
loading = false;
|
||||
endReached = true;
|
||||
otherItem.setVisibility(View.GONE);
|
||||
listViewAdapter.notifyDataSetChanged();
|
||||
} else {
|
||||
getMessagesController().deleteMessages(new ArrayList<>(selectedIds), null, null, 0, 0, checks[0], false);
|
||||
}
|
||||
hideActionMode(false);
|
||||
});
|
||||
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
|
||||
AlertDialog alertDialog = builder.create();
|
||||
showDialog(alertDialog);
|
||||
TextView button = (TextView) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
if (button != null) {
|
||||
button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2));
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteAllMessages(boolean revoke) {
|
||||
TLRPC.TL_messages_deletePhoneCallHistory req = new TLRPC.TL_messages_deletePhoneCallHistory();
|
||||
req.revoke = revoke;
|
||||
getConnectionsManager().sendRequest(req, (response, error) -> {
|
||||
if (response != null) {
|
||||
TLRPC.TL_messages_affectedFoundMessages res = (TLRPC.TL_messages_affectedFoundMessages) response;
|
||||
TLRPC.TL_updateDeleteMessages updateDeleteMessages = new TLRPC.TL_updateDeleteMessages();
|
||||
updateDeleteMessages.messages = res.messages;
|
||||
updateDeleteMessages.pts = res.pts;
|
||||
updateDeleteMessages.pts_count = res.pts_count;
|
||||
final TLRPC.TL_updates updates = new TLRPC.TL_updates();
|
||||
updates.updates.add(updateDeleteMessages);
|
||||
getMessagesController().processUpdates(updates, false);
|
||||
if (res.offset != 0) {
|
||||
deleteAllMessages(revoke);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void hideActionMode(boolean animated) {
|
||||
actionBar.hideActionMode();
|
||||
selectedIds.clear();
|
||||
for (int a = 0, N = listView.getChildCount(); a < N; a++) {
|
||||
CustomCell cell = (CustomCell) listView.getChildAt(a);
|
||||
cell.setChecked(false, animated);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSelected(ArrayList<TLRPC.Message> messages) {
|
||||
for (int a = 0, N = messages.size(); a < N; a++) {
|
||||
if (selectedIds.contains(messages.get(a).id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createActionMode() {
|
||||
if (actionBar.actionModeIsExist(null)) {
|
||||
return;
|
||||
}
|
||||
final ActionBarMenu actionMode = actionBar.createActionMode();
|
||||
|
||||
selectedDialogsCountTextView = new NumberTextView(actionMode.getContext());
|
||||
selectedDialogsCountTextView.setTextSize(18);
|
||||
selectedDialogsCountTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
selectedDialogsCountTextView.setTextColor(Theme.getColor(Theme.key_actionBarActionModeDefaultIcon));
|
||||
actionMode.addView(selectedDialogsCountTextView, LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, 72, 0, 0, 0));
|
||||
selectedDialogsCountTextView.setOnTouchListener((v, event) -> true);
|
||||
|
||||
actionModeViews.add(actionMode.addItemWithWidth(delete, R.drawable.msg_delete, AndroidUtilities.dp(54), LocaleController.getString("Delete", R.string.Delete)));
|
||||
}
|
||||
|
||||
private boolean addOrRemoveSelectedDialog(ArrayList<TLRPC.Message> messages, CustomCell cell) {
|
||||
if (messages.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (isSelected(messages)) {
|
||||
for (int a = 0, N = messages.size(); a < N; a++) {
|
||||
selectedIds.remove((Integer) messages.get(a).id);
|
||||
}
|
||||
cell.setChecked(false, true);
|
||||
showOrUpdateActionMode();
|
||||
return false;
|
||||
} else {
|
||||
for (int a = 0, N = messages.size(); a < N; a++) {
|
||||
Integer id = messages.get(a).id;
|
||||
if (!selectedIds.contains(id)) {
|
||||
selectedIds.add(id);
|
||||
}
|
||||
}
|
||||
cell.setChecked(true, true);
|
||||
showOrUpdateActionMode();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void showOrUpdateActionMode() {
|
||||
boolean updateAnimated = false;
|
||||
if (actionBar.isActionModeShowed()) {
|
||||
if (selectedIds.isEmpty()) {
|
||||
hideActionMode(true);
|
||||
return;
|
||||
}
|
||||
updateAnimated = true;
|
||||
} else {
|
||||
createActionMode();
|
||||
actionBar.showActionMode();
|
||||
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
ArrayList<Animator> animators = new ArrayList<>();
|
||||
for (int a = 0; a < actionModeViews.size(); a++) {
|
||||
View view = actionModeViews.get(a);
|
||||
view.setPivotY(ActionBar.getCurrentActionBarHeight() / 2);
|
||||
AndroidUtilities.clearDrawableAnimation(view);
|
||||
animators.add(ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.1f, 1.0f));
|
||||
}
|
||||
animatorSet.playTogether(animators);
|
||||
animatorSet.setDuration(200);
|
||||
animatorSet.start();
|
||||
}
|
||||
selectedDialogsCountTextView.setNumber(selectedIds.size(), updateAnimated);
|
||||
}
|
||||
|
||||
private void hideFloatingButton(boolean hide) {
|
||||
if (floatingHidden == hide) {
|
||||
return;
|
||||
|
@ -397,6 +592,7 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
req.q = "";
|
||||
req.offset_id = max_id;
|
||||
int reqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
int oldCount = calls.size();
|
||||
if (error == null) {
|
||||
SparseArray<TLRPC.User> users = new SparseArray<>();
|
||||
TLRPC.messages_Messages msgs = (TLRPC.messages_Messages) response;
|
||||
|
@ -438,7 +634,12 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
endReached = true;
|
||||
}
|
||||
loading = false;
|
||||
showItemsAnimated(oldCount);
|
||||
if (!firstLoaded) {
|
||||
resumeDelayedFragmentAnimation();
|
||||
}
|
||||
firstLoaded = true;
|
||||
otherItem.setVisibility(calls.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
if (emptyView != null) {
|
||||
emptyView.showTextView();
|
||||
}
|
||||
|
@ -449,25 +650,6 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
ConnectionsManager.getInstance(currentAccount).bindRequestToGuid(reqId, classGuid);
|
||||
}
|
||||
|
||||
private void confirmAndDelete(final CallLogRow row) {
|
||||
if (getParentActivity() == null) {
|
||||
return;
|
||||
}
|
||||
new AlertDialog.Builder(getParentActivity())
|
||||
.setTitle(LocaleController.getString("AppName", R.string.AppName))
|
||||
.setMessage(LocaleController.getString("ConfirmDeleteCallLog", R.string.ConfirmDeleteCallLog))
|
||||
.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), (dialog, which) -> {
|
||||
ArrayList<Integer> ids = new ArrayList<>();
|
||||
for (TLRPC.Message msg : row.calls) {
|
||||
ids.add(msg.id);
|
||||
}
|
||||
MessagesController.getInstance(currentAccount).deleteMessages(ids, null, null, 0, 0, false, false);
|
||||
})
|
||||
.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null)
|
||||
.show()
|
||||
.setCanceledOnTouchOutside(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -529,7 +711,12 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
view.setTag(new ViewItem(cell.imageView, cell.profileSearchCell));
|
||||
break;
|
||||
case 1:
|
||||
view = new LoadingCell(mContext);
|
||||
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(mContext);
|
||||
flickerLoadingView.setIsSingleCell(true);
|
||||
flickerLoadingView.setViewType(FlickerLoadingView.CALL_LOG_TYPE);
|
||||
flickerLoadingView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
|
||||
flickerLoadingView.showDate(false);
|
||||
view = flickerLoadingView;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
|
@ -540,6 +727,14 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
return new RecyclerListView.Holder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
|
||||
if (holder.itemView instanceof CustomCell) {
|
||||
CallLogRow row = calls.get(holder.getAdapterPosition());
|
||||
((CustomCell) holder.itemView).setChecked(isSelected(row.calls), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||
if (holder.getItemViewType() == 0) {
|
||||
|
@ -599,7 +794,7 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
|
||||
private static class CallLogRow {
|
||||
public TLRPC.User user;
|
||||
public List<TLRPC.Message> calls;
|
||||
public ArrayList<TLRPC.Message> calls;
|
||||
public int type;
|
||||
public boolean video;
|
||||
}
|
||||
|
@ -665,7 +860,81 @@ public class CallLogActivity extends BaseFragment implements NotificationCenter.
|
|||
|
||||
themeDescriptions.add(new ThemeDescription(listView, 0, new Class[]{View.class}, null, new Drawable[]{greenDrawable, greenDrawable2, Theme.calllog_msgCallUpRedDrawable, Theme.calllog_msgCallDownRedDrawable}, null, Theme.key_calls_callReceivedGreenIcon));
|
||||
themeDescriptions.add(new ThemeDescription(listView, 0, new Class[]{View.class}, null, new Drawable[]{redDrawable, Theme.calllog_msgCallUpGreenDrawable, Theme.calllog_msgCallDownGreenDrawable}, null, Theme.key_calls_callReceivedRedIcon));
|
||||
themeDescriptions.add(new ThemeDescription(flickerLoadingView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
|
||||
|
||||
return themeDescriptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTransitionAnimationStart(boolean isOpen, boolean backward) {
|
||||
super.onTransitionAnimationStart(isOpen, backward);
|
||||
if (isOpen) {
|
||||
openTransitionStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needDelayOpenAnimation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void showItemsAnimated(int from) {
|
||||
if (isPaused || !openTransitionStarted) {
|
||||
return;
|
||||
}
|
||||
View progressView = null;
|
||||
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||
View child = listView.getChildAt(i);
|
||||
if (child instanceof FlickerLoadingView) {
|
||||
progressView = child;
|
||||
}
|
||||
}
|
||||
final View finalProgressView = progressView;
|
||||
if (progressView != null) {
|
||||
listView.removeView(progressView);
|
||||
}
|
||||
|
||||
listView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
listView.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
int n = listView.getChildCount();
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
for (int i = 0; i < n; i++) {
|
||||
View child = listView.getChildAt(i);
|
||||
if (child == finalProgressView || listView.getChildAdapterPosition(child) < from) {
|
||||
continue;
|
||||
}
|
||||
child.setAlpha(0);
|
||||
int s = Math.min(listView.getMeasuredHeight(), Math.max(0, child.getTop()));
|
||||
int delay = (int) ((s / (float) listView.getMeasuredHeight()) * 100);
|
||||
ObjectAnimator a = ObjectAnimator.ofFloat(child, View.ALPHA, 0, 1f);
|
||||
a.setStartDelay(delay);
|
||||
a.setDuration(200);
|
||||
animatorSet.playTogether(a);
|
||||
}
|
||||
|
||||
if (finalProgressView != null && finalProgressView.getParent() == null) {
|
||||
listView.addView(finalProgressView);
|
||||
RecyclerView.LayoutManager layoutManager = listView.getLayoutManager();
|
||||
if (layoutManager != null) {
|
||||
layoutManager.ignoreView(finalProgressView);
|
||||
Animator animator = ObjectAnimator.ofFloat(finalProgressView, View.ALPHA, finalProgressView.getAlpha(), 0);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
finalProgressView.setAlpha(1f);
|
||||
layoutManager.stopIgnoringView(finalProgressView);
|
||||
listView.removeView(finalProgressView);
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
|
||||
animatorSet.start();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.telegram.messenger.SharedConfig;
|
|||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.DotDividerSpan;
|
||||
import org.telegram.ui.Components.MediaActionDrawable;
|
||||
import org.telegram.ui.Components.RadialProgress2;
|
||||
import org.telegram.ui.FilteredSearchView;
|
||||
|
@ -85,25 +86,7 @@ public class AudioPlayerCell extends View implements DownloadController.FileDown
|
|||
|
||||
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
|
||||
dotSpan = new SpannableStringBuilder(".");
|
||||
dotSpan.setSpan(new ReplacementSpan() {
|
||||
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
int color;
|
||||
|
||||
@Override
|
||||
public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) {
|
||||
return AndroidUtilities.dp(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
|
||||
if (color != paint.getColor()) {
|
||||
p.setColor(paint.getColor());
|
||||
}
|
||||
float radius = AndroidUtilities.dpf2(3) / 2f;
|
||||
canvas.drawCircle(x + radius, (bottom - top) / 2, radius, p);
|
||||
}
|
||||
}, 0, 1, 0);
|
||||
dotSpan.setSpan(new DotDividerSpan(), 0, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
default void didPressOther(ChatMessageCell cell, float otherX, float otherY) {
|
||||
}
|
||||
|
||||
default void didPressTime(ChatMessageCell cell) {
|
||||
}
|
||||
|
||||
default void didPressBotButton(ChatMessageCell cell, TLRPC.KeyboardButton button) {
|
||||
}
|
||||
|
||||
|
@ -458,6 +461,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
private String currentPhotoFilter;
|
||||
private String currentPhotoFilterThumb;
|
||||
|
||||
private boolean timePressed;
|
||||
|
||||
private float timeAlpha = 1.0f;
|
||||
private float controlsAlpha = 1.0f;
|
||||
private long lastControlsAlphaChangeTime;
|
||||
|
@ -673,6 +678,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
private int forwardNameY;
|
||||
private float[] forwardNameOffsetX = new float[2];
|
||||
|
||||
private float drawTimeX;
|
||||
private float drawTimeY;
|
||||
private StaticLayout timeLayout;
|
||||
private int timeWidth;
|
||||
private int timeTextWidth;
|
||||
|
@ -739,6 +746,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
private ValueAnimator statusDrawableAnimator;
|
||||
|
||||
private int overideShouldDrawTimeOnMedia;
|
||||
private float toSeekBarProgress;
|
||||
|
||||
private Runnable invalidateRunnable = new Runnable() {
|
||||
@Override
|
||||
|
@ -1638,6 +1646,34 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
return result;
|
||||
}
|
||||
|
||||
private boolean checkDateMotionEvent(MotionEvent event) {
|
||||
if (!currentMessageObject.isImportedForward()) {
|
||||
return false;
|
||||
}
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
|
||||
boolean result = false;
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
if (x >= drawTimeX && x <= drawTimeX + timeWidth && y >= drawTimeY && y <= drawTimeY + AndroidUtilities.dp(20)) {
|
||||
timePressed = true;
|
||||
result = true;
|
||||
invalidate();
|
||||
}
|
||||
} else {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (timePressed) {
|
||||
timePressed = false;
|
||||
playSoundEffect(SoundEffectConstants.CLICK);
|
||||
delegate.didPressTime(this);
|
||||
invalidate();
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean checkPhotoImageMotionEvent(MotionEvent event) {
|
||||
if (!drawPhotoImage && documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT || currentMessageObject.isSending() && buttonState != 1) {
|
||||
return false;
|
||||
|
@ -1884,6 +1920,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
|
||||
boolean result = checkTextBlockMotionEvent(event);
|
||||
|
||||
if (!result) {
|
||||
result = checkDateMotionEvent(event);
|
||||
}
|
||||
if (!result) {
|
||||
result = checkTextSelection(event);
|
||||
}
|
||||
|
@ -1929,6 +1968,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
otherPressed = false;
|
||||
sideButtonPressed = false;
|
||||
imagePressed = false;
|
||||
timePressed = false;
|
||||
gamePreviewPressed = false;
|
||||
instantPressed = instantButtonPressed = commentButtonPressed = false;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
|
@ -2666,6 +2706,18 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
return (int) (forwardNameX + forwardNameCenterX);
|
||||
}
|
||||
|
||||
public int getChecksX() {
|
||||
return layoutWidth - AndroidUtilities.dp(SharedConfig.bubbleRadius >= 10 ? 27.3f : 25.3f);
|
||||
}
|
||||
|
||||
public int getChecksY() {
|
||||
if (currentMessageObject.shouldDrawWithoutBackground()) {
|
||||
return (int) (drawTimeY - Theme.chat_msgStickerCheckDrawable.getIntrinsicHeight());
|
||||
} else {
|
||||
return (int) (drawTimeY - Theme.chat_msgMediaCheckDrawable.getIntrinsicHeight());
|
||||
}
|
||||
}
|
||||
|
||||
public TLRPC.User getCurrentUser() {
|
||||
return currentUser;
|
||||
}
|
||||
|
@ -2798,6 +2850,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
if (getDelegate().getTextSelectionHelper() != null) {
|
||||
getDelegate().getTextSelectionHelper().onChatMessageCellAttached(this);
|
||||
}
|
||||
|
||||
if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
|
||||
boolean showSeekbar = MediaController.getInstance().isPlayingMessage(currentMessageObject);
|
||||
toSeekBarProgress = showSeekbar ? 1f : 0f;
|
||||
}
|
||||
}
|
||||
|
||||
private void setMessageContent(MessageObject messageObject, MessageObject.GroupedMessages groupedMessages, boolean bottomNear, boolean topNear) {
|
||||
|
@ -3151,7 +3208,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
} else {
|
||||
maxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80);
|
||||
}
|
||||
drawName = isPinnedChat || messageObject.messageOwner.peer_id.channel_id != 0 && (!messageObject.isOutOwner() || messageObject.isSupergroup());
|
||||
drawName = isPinnedChat || messageObject.messageOwner.peer_id.channel_id != 0 && (!messageObject.isOutOwner() || messageObject.isSupergroup()) || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null;
|
||||
}
|
||||
|
||||
availableTimeWidth = maxWidth;
|
||||
|
@ -4098,7 +4155,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
namesOffset -= AndroidUtilities.dp(1);
|
||||
}
|
||||
} else if (messageObject.type == 12) {
|
||||
drawName = messageObject.isFromGroup() && messageObject.isSupergroup();
|
||||
drawName = messageObject.isFromGroup() && messageObject.isSupergroup() || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null;
|
||||
drawForwardedName = !isRepliesChat;
|
||||
drawPhotoImage = true;
|
||||
photoImage.setRoundRadius(AndroidUtilities.dp(22));
|
||||
|
@ -4181,7 +4238,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
}
|
||||
} else if (messageObject.type == 2) {
|
||||
drawForwardedName = !isRepliesChat;
|
||||
drawName = messageObject.isFromGroup() && messageObject.isSupergroup();
|
||||
drawName = messageObject.isFromGroup() && messageObject.isSupergroup() || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null;
|
||||
if (AndroidUtilities.isTablet()) {
|
||||
backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
|
||||
} else {
|
||||
|
@ -4196,7 +4253,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
namesOffset -= AndroidUtilities.dp(1);
|
||||
}
|
||||
} else if (messageObject.type == 14) {
|
||||
drawName = messageObject.isFromGroup() && messageObject.isSupergroup() && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0);
|
||||
drawName = (messageObject.isFromGroup() && messageObject.isSupergroup() || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null) && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0);
|
||||
if (AndroidUtilities.isTablet()) {
|
||||
backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(drawAvatar ? 102 : 50), AndroidUtilities.dp(270));
|
||||
} else {
|
||||
|
@ -4492,7 +4549,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
} else {
|
||||
drawForwardedName = messageObject.messageOwner.fwd_from != null && !messageObject.isAnyKindOfSticker();
|
||||
if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
|
||||
drawName = messageObject.isFromGroup() && messageObject.isSupergroup() && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0);
|
||||
drawName = (messageObject.isFromGroup() && messageObject.isSupergroup() || messageObject.isImportedForward() && messageObject.messageOwner.fwd_from.from_id == null) && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0);
|
||||
}
|
||||
mediaBackground = isMedia = messageObject.type != 9;
|
||||
drawImageButton = true;
|
||||
|
@ -5747,6 +5804,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
}
|
||||
transitionParams.lastStatusDrawableParams = -1;
|
||||
statusDrawableAnimationInProgress = false;
|
||||
|
||||
if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
|
||||
boolean showSeekbar = MediaController.getInstance().isPlayingMessage(currentMessageObject);
|
||||
toSeekBarProgress = showSeekbar ? 1f : 0f;
|
||||
}
|
||||
}
|
||||
updateWaveform();
|
||||
updateButtonState(false, dataChanged && !messageObject.cancelEditing, true);
|
||||
|
@ -5813,6 +5875,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
linkPreviewPressed = false;
|
||||
sideButtonPressed = false;
|
||||
imagePressed = false;
|
||||
timePressed = false;
|
||||
gamePreviewPressed = false;
|
||||
|
||||
if (pressedVoteButton != -1 || pollHintPressed || psaHintPressed || instantPressed || otherPressed || commentButtonPressed) {
|
||||
|
@ -6006,6 +6069,17 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
}
|
||||
currentMessageObject.audioProgress = progress;
|
||||
MediaController.getInstance().seekToProgress(currentMessageObject, progress);
|
||||
updatePlayingMessageProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSeekBarContinuousDrag(float progress) {
|
||||
if (currentMessageObject == null) {
|
||||
return;
|
||||
}
|
||||
currentMessageObject.audioProgress = progress;
|
||||
currentMessageObject.audioProgressSec = (int) (currentMessageObject.getDuration() * progress);
|
||||
updatePlayingMessageProgress();
|
||||
}
|
||||
|
||||
public boolean isAnimatingPollAnswer() {
|
||||
|
@ -7348,16 +7422,47 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
canvas.translate(timeAudioX + songX, AndroidUtilities.dp(13) + namesOffset + mediaOffsetY);
|
||||
songLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
|
||||
|
||||
boolean showSeekbar = MediaController.getInstance().isPlayingMessage(currentMessageObject);
|
||||
if (showSeekbar && toSeekBarProgress != 1f) {
|
||||
toSeekBarProgress += 16f / 100f;
|
||||
if (toSeekBarProgress > 1f) {
|
||||
toSeekBarProgress = 1f;
|
||||
}
|
||||
invalidate();
|
||||
} else if (!showSeekbar && toSeekBarProgress != 0){
|
||||
toSeekBarProgress -= 16f / 100f;
|
||||
if (toSeekBarProgress < 0) {
|
||||
toSeekBarProgress = 0;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
if (toSeekBarProgress > 0) {
|
||||
if (toSeekBarProgress != 1f) {
|
||||
canvas.saveLayerAlpha(seekBarX, seekBarY, seekBarX + seekBar.getWidth() + AndroidUtilities.dp(24), seekBarY + AndroidUtilities.dp(24), (int) (255 * (toSeekBarProgress)), Canvas.ALL_SAVE_FLAG);
|
||||
} else {
|
||||
canvas.save();
|
||||
}
|
||||
canvas.translate(seekBarX, seekBarY);
|
||||
seekBar.draw(canvas);
|
||||
} else {
|
||||
canvas.translate(timeAudioX + performerX, AndroidUtilities.dp(35) + namesOffset + mediaOffsetY);
|
||||
performerLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
if (toSeekBarProgress < 1f) {
|
||||
float x = timeAudioX + performerX;
|
||||
float y = AndroidUtilities.dp(35) + namesOffset + mediaOffsetY;
|
||||
if (toSeekBarProgress != 0) {
|
||||
canvas.saveLayerAlpha(x, y, x + performerLayout.getWidth(), y + performerLayout.getHeight(), (int) (255 * (1f - toSeekBarProgress)), Canvas.ALL_SAVE_FLAG);
|
||||
} else {
|
||||
canvas.save();
|
||||
}
|
||||
if (toSeekBarProgress != 0) {
|
||||
float s = 0.7f + 0.3f * (1f - toSeekBarProgress);
|
||||
canvas.scale(s, s, x, y + performerLayout.getHeight() / 2f);
|
||||
}
|
||||
canvas.translate(x, y);
|
||||
performerLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(timeAudioX, AndroidUtilities.dp(57) + namesOffset + mediaOffsetY);
|
||||
|
@ -7971,7 +8076,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
hasMiniProgress = fileExists ? 1 : 2;
|
||||
fileExists = true;
|
||||
}
|
||||
if (currentMessageObject.isSendError() || TextUtils.isEmpty(fileName) && !currentMessageObject.isSending() && !currentMessageObject.isEditing()) {
|
||||
if (currentMessageObject.isSendError() || TextUtils.isEmpty(fileName) && (currentMessageObject.isAnyKindOfSticker() || !currentMessageObject.isSending() && !currentMessageObject.isEditing())) {
|
||||
radialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
|
||||
radialProgress.setMiniIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
|
||||
videoRadialProgress.setIcon(MediaActionDrawable.ICON_NONE, ifSame, false);
|
||||
|
@ -8817,6 +8922,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
}
|
||||
} else if (messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.post_author != null) {
|
||||
signString = messageObject.messageOwner.fwd_from.post_author.replace("\n", "");
|
||||
} else if (messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.imported) {
|
||||
signString = LocaleController.formatImportedDate(messageObject.messageOwner.fwd_from.date) + " " + LocaleController.getString("ImportedMessage", R.string.ImportedMessage);
|
||||
} else if (!messageObject.isOutOwner() && fromId > 0 && messageObject.messageOwner.post) {
|
||||
TLRPC.User signUser = MessagesController.getInstance(currentAccount).getUser(fromId);
|
||||
if (signUser != null) {
|
||||
|
@ -8856,7 +8963,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
timeString = LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
|
||||
}
|
||||
if (signString != null) {
|
||||
currentTimeString = ", " + timeString;
|
||||
if (messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.imported) {
|
||||
currentTimeString = " " + timeString;
|
||||
} else {
|
||||
currentTimeString = ", " + timeString;
|
||||
}
|
||||
} else {
|
||||
currentTimeString = timeString;
|
||||
}
|
||||
|
@ -8964,9 +9075,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
currentChat = messagesController.getChat(fwd_from.saved_from_peer.chat_id);
|
||||
}
|
||||
}
|
||||
} else if (fwd_from != null && fwd_from.from_id instanceof TLRPC.TL_peerUser && currentMessageObject.getDialogId() == currentUserId) {
|
||||
} else if (fwd_from != null && fwd_from.from_id instanceof TLRPC.TL_peerUser && (fwd_from.imported || currentMessageObject.getDialogId() == currentUserId)) {
|
||||
currentUser = messagesController.getUser(fwd_from.from_id.user_id);
|
||||
} else if (fwd_from != null && !TextUtils.isEmpty(fwd_from.from_name) && currentMessageObject.getDialogId() == currentUserId) {
|
||||
} else if (fwd_from != null && !TextUtils.isEmpty(fwd_from.from_name) && (fwd_from.imported || currentMessageObject.getDialogId() == currentUserId)) {
|
||||
currentUser = new TLRPC.TL_user();
|
||||
currentUser.first_name = fwd_from.from_name;
|
||||
} else {
|
||||
|
@ -9026,13 +9137,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
CharSequence viaString = null;
|
||||
if (messageObject.messageOwner.via_bot_id != 0) {
|
||||
TLRPC.User botUser = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.via_bot_id);
|
||||
if (botUser != null && botUser.username != null && botUser.username.length() > 0) {
|
||||
if (botUser != null && !TextUtils.isEmpty(botUser.username)) {
|
||||
viaUsername = "@" + botUser.username;
|
||||
viaString = AndroidUtilities.replaceTags(String.format(" %s <b>%s</b>", LocaleController.getString("ViaBot", R.string.ViaBot), viaUsername));
|
||||
viaWidth = (int) Math.ceil(Theme.chat_replyNamePaint.measureText(viaString, 0, viaString.length()));
|
||||
currentViaBotUser = botUser;
|
||||
}
|
||||
} else if (messageObject.messageOwner.via_bot_name != null && messageObject.messageOwner.via_bot_name.length() > 0) {
|
||||
} else if (!TextUtils.isEmpty(messageObject.messageOwner.via_bot_name)) {
|
||||
viaUsername = "@" + messageObject.messageOwner.via_bot_name;
|
||||
viaString = AndroidUtilities.replaceTags(String.format(" %s <b>%s</b>", LocaleController.getString("ViaBot", R.string.ViaBot), viaUsername));
|
||||
viaWidth = (int) Math.ceil(Theme.chat_replyNamePaint.measureText(viaString, 0, viaString.length()));
|
||||
|
@ -9074,7 +9185,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
} else {
|
||||
currentNameString = "";
|
||||
}
|
||||
CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace('\n', ' '), Theme.chat_namePaint, nameWidth - (viaBot ? viaWidth : 0), TextUtils.TruncateAt.END);
|
||||
CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace('\n', ' ').replace('\u200F', ' '), Theme.chat_namePaint, nameWidth - (viaBot ? viaWidth : 0), TextUtils.TruncateAt.END);
|
||||
if (viaBot) {
|
||||
viaNameWidth = (int) Math.ceil(Theme.chat_namePaint.measureText(nameStringFinal, 0, nameStringFinal.length()));
|
||||
if (viaNameWidth != 0) {
|
||||
|
@ -9414,7 +9525,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
}
|
||||
|
||||
private boolean isNeedAuthorName() {
|
||||
return isPinnedChat && currentMessageObject.type == 0 || (!pinnedTop || ChatObject.isChannel(currentChat) && !currentChat.megagroup) && drawName && isChat && (!currentMessageObject.isOutOwner() || currentMessageObject.isSupergroup() && currentMessageObject.isFromGroup());
|
||||
return isPinnedChat && currentMessageObject.type == 0 || (!pinnedTop || ChatObject.isChannel(currentChat) && !currentChat.megagroup) && drawName && isChat && (!currentMessageObject.isOutOwner() || currentMessageObject.isSupergroup() && currentMessageObject.isFromGroup()) || currentMessageObject.isImportedForward() && currentMessageObject.messageOwner.fwd_from.from_id == null;
|
||||
}
|
||||
|
||||
private String getAuthorName() {
|
||||
|
@ -10871,7 +10982,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
if (overideShouldDrawTimeOnMedia != 0) {
|
||||
return overideShouldDrawTimeOnMedia == 1;
|
||||
}
|
||||
return mediaBackground && captionLayout == null || isMedia && drawCommentButton && !isRepliesChat;
|
||||
return mediaBackground && captionLayout == null/* || isMedia && drawCommentButton && !isRepliesChat*/;
|
||||
}
|
||||
|
||||
public void drawTime(Canvas canvas, float alpha, boolean fromParent) {
|
||||
|
@ -11027,7 +11138,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
}
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(timeTitleTimeX + additionalX, timeY - AndroidUtilities.dp(7.3f) - timeLayout.getHeight());
|
||||
canvas.translate(drawTimeX = timeTitleTimeX + additionalX, drawTimeY = timeY - AndroidUtilities.dp(7.3f) - timeLayout.getHeight());
|
||||
timeLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
Theme.chat_timePaint.setAlpha(255);
|
||||
|
@ -11086,7 +11197,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
Theme.chat_timePaint.setAlpha(oldAlpha);
|
||||
}
|
||||
} else {
|
||||
canvas.translate(timeTitleTimeX + additionalX, layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 7.5f : 6.5f) - timeLayout.getHeight() + timeYOffset);
|
||||
canvas.translate(drawTimeX = timeTitleTimeX + additionalX, drawTimeY = layoutHeight - AndroidUtilities.dp(pinnedBottom || pinnedTop ? 7.5f : 6.5f) - timeLayout.getHeight() + timeYOffset);
|
||||
timeLayout.draw(canvas);
|
||||
}
|
||||
canvas.restore();
|
||||
|
@ -12729,6 +12840,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
super.setTranslationX(translationX);
|
||||
}
|
||||
|
||||
public SeekBar getSeekBar() {
|
||||
return seekBar;
|
||||
}
|
||||
|
||||
private class MessageAccessibilityNodeProvider extends AccessibilityNodeProvider {
|
||||
|
||||
private final int LINK_IDS_START = 2000;
|
||||
|
@ -12738,6 +12853,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
private final int SHARE = 498;
|
||||
private final int REPLY = 497;
|
||||
private final int COMMENT = 496;
|
||||
private final int POLL_HINT = 495;
|
||||
private Path linkPath = new Path();
|
||||
private RectF rectF = new RectF();
|
||||
private Rect rect = new Rect();
|
||||
|
@ -12900,6 +13016,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
info.addChild(ChatMessageCell.this, BOT_BUTTONS_START + i);
|
||||
i++;
|
||||
}
|
||||
if (hintButtonVisible && pollHintX != -1 && currentMessageObject.isPoll()) {
|
||||
info.addChild(ChatMessageCell.this, POLL_HINT);
|
||||
}
|
||||
i = 0;
|
||||
for (PollButton button : pollButtons) {
|
||||
info.addChild(ChatMessageCell.this, POLL_BUTTONS_START + i);
|
||||
|
@ -12991,17 +13110,23 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
return null;
|
||||
}
|
||||
PollButton button = pollButtons.get(buttonIndex);
|
||||
info.setText(button.title.getText());
|
||||
StringBuilder sb = new StringBuilder(button.title.getText());
|
||||
if (!pollVoted) {
|
||||
info.setClassName("android.widget.Button");
|
||||
} else {
|
||||
info.setText(info.getText() + ", " + button.percent + "%");
|
||||
info.setSelected(button.chosen);
|
||||
sb.append(", ").append(button.percent).append("%");
|
||||
if (lastPoll != null && lastPoll.quiz && button.correct) {
|
||||
sb.append(", ").append(LocaleController.getString("AccDescrQuizCorrectAnswer", R.string.AccDescrQuizCorrectAnswer));
|
||||
}
|
||||
}
|
||||
info.setText(sb);
|
||||
info.setEnabled(true);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
|
||||
|
||||
int width = backgroundWidth - AndroidUtilities.dp(76);
|
||||
rect.set(button.x, button.y, button.x + width, button.y + button.height);
|
||||
final int y = button.y + namesOffset;
|
||||
final int w = backgroundWidth - AndroidUtilities.dp(76);
|
||||
rect.set(button.x, y, button.x + w, y + button.height);
|
||||
info.setBoundsInParent(rect);
|
||||
if (accessibilityVirtualViewBounds.get(virtualViewId) == null) {
|
||||
accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
|
||||
|
@ -13009,6 +13134,19 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
rect.offset(pos[0], pos[1]);
|
||||
info.setBoundsInScreen(rect);
|
||||
|
||||
info.setClickable(true);
|
||||
} else if (virtualViewId == POLL_HINT) {
|
||||
info.setClassName("android.widget.Button");
|
||||
info.setEnabled(true);
|
||||
info.setText(LocaleController.getString("AccDescrQuizExplanation", R.string.AccDescrQuizExplanation));
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
|
||||
rect.set(pollHintX - AndroidUtilities.dp(8), pollHintY - AndroidUtilities.dp(8), pollHintX + AndroidUtilities.dp(32), pollHintY + AndroidUtilities.dp(32));
|
||||
info.setBoundsInParent(rect);
|
||||
if (accessibilityVirtualViewBounds.get(virtualViewId) == null || !accessibilityVirtualViewBounds.get(virtualViewId).equals(rect)) {
|
||||
accessibilityVirtualViewBounds.put(virtualViewId, new Rect(rect));
|
||||
}
|
||||
rect.offset(pos[0], pos[1]);
|
||||
info.setBoundsInScreen(rect);
|
||||
info.setClickable(true);
|
||||
} else if (virtualViewId == INSTANT_VIEW) {
|
||||
info.setClassName("android.widget.Button");
|
||||
|
@ -13128,6 +13266,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
delegate.didPressVoteButtons(ChatMessageCell.this, answers, -1, 0, 0);
|
||||
}
|
||||
sendAccessibilityEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
|
||||
} else if (virtualViewId == POLL_HINT) {
|
||||
if (delegate != null) {
|
||||
delegate.didPressHint(ChatMessageCell.this, 0);
|
||||
}
|
||||
} else if (virtualViewId == INSTANT_VIEW) {
|
||||
if (delegate != null) {
|
||||
delegate.didPressInstantButton(ChatMessageCell.this, drawInstantViewType);
|
||||
|
|
|
@ -253,7 +253,7 @@ public class DialogCell extends BaseCell {
|
|||
|
||||
private boolean drawVerified;
|
||||
|
||||
private boolean drawScam;
|
||||
private int drawScam;
|
||||
|
||||
private boolean isSelected;
|
||||
|
||||
|
@ -269,6 +269,8 @@ public class DialogCell extends BaseCell {
|
|||
long lastDialogChangedTime;
|
||||
private int statusDrawableLeft;
|
||||
|
||||
private DialogsActivity parentFragment;
|
||||
|
||||
public static class BounceInterpolator implements Interpolator {
|
||||
|
||||
public float getInterpolation(float t) {
|
||||
|
@ -286,13 +288,13 @@ public class DialogCell extends BaseCell {
|
|||
}
|
||||
}
|
||||
|
||||
public DialogCell(Context context, boolean needCheck, boolean forceThreeLines) {
|
||||
this(context, needCheck, forceThreeLines, UserConfig.selectedAccount);
|
||||
public DialogCell(DialogsActivity fragment, Context context, boolean needCheck, boolean forceThreeLines) {
|
||||
this(fragment, context, needCheck, forceThreeLines, UserConfig.selectedAccount);
|
||||
}
|
||||
|
||||
public DialogCell(Context context, boolean needCheck, boolean forceThreeLines, int account) {
|
||||
public DialogCell(DialogsActivity fragment, Context context, boolean needCheck, boolean forceThreeLines, int account) {
|
||||
super(context);
|
||||
|
||||
parentFragment = fragment;
|
||||
Theme.createDialogsResources(context);
|
||||
avatarImage.setRoundRadius(AndroidUtilities.dp(28));
|
||||
thumbImage.setRoundRadius(AndroidUtilities.dp(2));
|
||||
|
@ -564,7 +566,7 @@ public class DialogCell extends BaseCell {
|
|||
drawNameLock = false;
|
||||
drawNameBot = false;
|
||||
drawVerified = false;
|
||||
drawScam = false;
|
||||
drawScam = 0;
|
||||
drawPinBackground = false;
|
||||
hasMessageThumb = false;
|
||||
int offsetName = 0;
|
||||
|
@ -744,8 +746,11 @@ public class DialogCell extends BaseCell {
|
|||
if (currentDialogFolderId == 0) {
|
||||
if (chat != null) {
|
||||
if (chat.scam) {
|
||||
drawScam = true;
|
||||
drawScam = 1;
|
||||
Theme.dialogs_scamDrawable.checkText();
|
||||
} else if (chat.fake) {
|
||||
drawScam = 2;
|
||||
Theme.dialogs_fakeDrawable.checkText();
|
||||
} else {
|
||||
drawVerified = chat.verified;
|
||||
}
|
||||
|
@ -786,8 +791,11 @@ public class DialogCell extends BaseCell {
|
|||
}
|
||||
} else if (user != null) {
|
||||
if (user.scam) {
|
||||
drawScam = true;
|
||||
drawScam = 1;
|
||||
Theme.dialogs_scamDrawable.checkText();
|
||||
} else if (user.fake) {
|
||||
drawScam = 2;
|
||||
Theme.dialogs_fakeDrawable.checkText();
|
||||
} else {
|
||||
drawVerified = user.verified;
|
||||
}
|
||||
|
@ -957,6 +965,8 @@ public class DialogCell extends BaseCell {
|
|||
if (chat != null && chat.id > 0 && fromChat == null && (!ChatObject.isChannel(chat) || ChatObject.isMegagroup(chat))) {
|
||||
if (message.isOutOwner()) {
|
||||
messageNameString = LocaleController.getString("FromYou", R.string.FromYou);
|
||||
} else if (message != null && message.messageOwner.fwd_from != null && message.messageOwner.fwd_from.from_name != null) {
|
||||
messageNameString = message.messageOwner.fwd_from.from_name;
|
||||
} else if (fromUser != null) {
|
||||
if (useForceThreeLines || SharedConfig.useThreeLinesLayout) {
|
||||
if (UserObject.isDeleted(fromUser)) {
|
||||
|
@ -1368,7 +1378,7 @@ public class DialogCell extends BaseCell {
|
|||
}
|
||||
}
|
||||
|
||||
if (dialogMuted && !drawVerified && !drawScam) {
|
||||
if (dialogMuted && !drawVerified && drawScam == 0) {
|
||||
int w = AndroidUtilities.dp(6) + Theme.dialogs_muteDrawable.getIntrinsicWidth();
|
||||
nameWidth -= w;
|
||||
if (LocaleController.isRTL) {
|
||||
|
@ -1380,8 +1390,8 @@ public class DialogCell extends BaseCell {
|
|||
if (LocaleController.isRTL) {
|
||||
nameLeft += w;
|
||||
}
|
||||
} else if (drawScam) {
|
||||
int w = AndroidUtilities.dp(6) + Theme.dialogs_scamDrawable.getIntrinsicWidth();
|
||||
} else if (drawScam != 0) {
|
||||
int w = AndroidUtilities.dp(6) + (drawScam == 0 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable).getIntrinsicWidth();
|
||||
nameWidth -= w;
|
||||
if (LocaleController.isRTL) {
|
||||
nameLeft += w;
|
||||
|
@ -1595,12 +1605,12 @@ public class DialogCell extends BaseCell {
|
|||
if (nameLayout != null && nameLayout.getLineCount() > 0) {
|
||||
left = nameLayout.getLineLeft(0);
|
||||
widthpx = Math.ceil(nameLayout.getLineWidth(0));
|
||||
if (dialogMuted && !drawVerified && !drawScam) {
|
||||
if (dialogMuted && !drawVerified && drawScam == 0) {
|
||||
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6) - Theme.dialogs_muteDrawable.getIntrinsicWidth());
|
||||
} else if (drawVerified) {
|
||||
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6) - Theme.dialogs_verifiedDrawable.getIntrinsicWidth());
|
||||
} else if (drawScam) {
|
||||
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6) - Theme.dialogs_scamDrawable.getIntrinsicWidth());
|
||||
} else if (drawScam != 0) {
|
||||
nameMuteLeft = (int) (nameLeft + (nameWidth - widthpx) - AndroidUtilities.dp(6) - (drawScam == 0 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable).getIntrinsicWidth());
|
||||
}
|
||||
if (left == 0) {
|
||||
if (widthpx < nameWidth) {
|
||||
|
@ -1645,7 +1655,7 @@ public class DialogCell extends BaseCell {
|
|||
nameLeft -= (nameWidth - widthpx);
|
||||
}
|
||||
}
|
||||
if (dialogMuted || drawVerified || drawScam) {
|
||||
if (dialogMuted || drawVerified || drawScam != 0) {
|
||||
nameMuteLeft = (int) (nameLeft + left + AndroidUtilities.dp(6));
|
||||
}
|
||||
}
|
||||
|
@ -1775,7 +1785,10 @@ public class DialogCell extends BaseCell {
|
|||
}
|
||||
|
||||
public void checkCurrentDialogIndex(boolean frozen) {
|
||||
ArrayList<TLRPC.Dialog> dialogsArray = DialogsActivity.getDialogsArray(currentAccount, dialogsType, folderId, frozen);
|
||||
if (parentFragment == null) {
|
||||
return;
|
||||
}
|
||||
ArrayList<TLRPC.Dialog> dialogsArray = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, frozen);
|
||||
if (index < dialogsArray.size()) {
|
||||
TLRPC.Dialog dialog = dialogsArray.get(index);
|
||||
TLRPC.Dialog nextDialog = index + 1 < dialogsArray.size() ? dialogsArray.get(index + 1) : null;
|
||||
|
@ -1849,7 +1862,10 @@ public class DialogCell extends BaseCell {
|
|||
}
|
||||
|
||||
private MessageObject findFolderTopMessage() {
|
||||
ArrayList<TLRPC.Dialog> dialogs = DialogsActivity.getDialogsArray(currentAccount, dialogsType, currentDialogFolderId, false);
|
||||
if (parentFragment == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<TLRPC.Dialog> dialogs = parentFragment.getDialogsArray(currentAccount, dialogsType, currentDialogFolderId, false);
|
||||
MessageObject maxMessage = null;
|
||||
if (!dialogs.isEmpty()) {
|
||||
for (int a = 0, N = dialogs.size(); a < N; a++) {
|
||||
|
@ -2165,7 +2181,7 @@ public class DialogCell extends BaseCell {
|
|||
}
|
||||
if (isSliding) {
|
||||
boolean prevValue = drawRevealBackground;
|
||||
drawRevealBackground = Math.abs(translationX) >= getMeasuredWidth() * 0.3f;
|
||||
drawRevealBackground = Math.abs(translationX) >= getMeasuredWidth() * 0.45f;
|
||||
if (prevValue != drawRevealBackground && archiveHidden == SharedConfig.archiveHidden) {
|
||||
try {
|
||||
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
|
||||
|
@ -2483,7 +2499,7 @@ public class DialogCell extends BaseCell {
|
|||
lastStatusDrawableParams = (this.drawClock ? 1 : 0) + (this.drawCheck1 ? 2 : 0) + (this.drawCheck2 ? 4 : 0);
|
||||
}
|
||||
|
||||
if (dialogMuted && !drawVerified && !drawScam) {
|
||||
if (dialogMuted && !drawVerified && drawScam == 0) {
|
||||
setDrawableBounds(Theme.dialogs_muteDrawable, nameMuteLeft - AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 0 : 1), AndroidUtilities.dp(SharedConfig.useThreeLinesLayout ? 13.5f : 17.5f));
|
||||
Theme.dialogs_muteDrawable.draw(canvas);
|
||||
} else if (drawVerified) {
|
||||
|
@ -2491,9 +2507,9 @@ public class DialogCell extends BaseCell {
|
|||
setDrawableBounds(Theme.dialogs_verifiedCheckDrawable, nameMuteLeft, AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 12.5f : 16.5f));
|
||||
Theme.dialogs_verifiedDrawable.draw(canvas);
|
||||
Theme.dialogs_verifiedCheckDrawable.draw(canvas);
|
||||
} else if (drawScam) {
|
||||
setDrawableBounds(Theme.dialogs_scamDrawable, nameMuteLeft, AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 12 : 15));
|
||||
Theme.dialogs_scamDrawable.draw(canvas);
|
||||
} else if (drawScam != 0) {
|
||||
setDrawableBounds((drawScam == 0 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable), nameMuteLeft, AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 12 : 15));
|
||||
(drawScam == 0 ? Theme.dialogs_scamDrawable : Theme.dialogs_fakeDrawable).draw(canvas);
|
||||
}
|
||||
|
||||
if (drawReorder || reorderIconProgress != 0) {
|
||||
|
@ -2970,7 +2986,7 @@ public class DialogCell extends BaseCell {
|
|||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
if (currentDialogFolderId != 0 && archiveHidden) {
|
||||
if (isFolderCell() && archivedChatsDrawable != null && archivedChatsDrawable.pullProgress == 0.0f) {
|
||||
info.setVisibleToUser(false);
|
||||
} else {
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
|
||||
|
@ -3075,6 +3091,10 @@ public class DialogCell extends BaseCell {
|
|||
archivedChatsDrawable = drawable;
|
||||
}
|
||||
|
||||
public int getCurrentDialogFolderId() {
|
||||
return currentDialogFolderId;
|
||||
}
|
||||
|
||||
public MessageObject getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ public class FeaturedStickerSetInfoCell extends FrameLayout {
|
|||
private CharSequence url;
|
||||
private int urlSearchLength;
|
||||
|
||||
float unreadProgress;
|
||||
|
||||
public FeaturedStickerSetInfoCell(Context context, int left) {
|
||||
this(context, left, false);
|
||||
}
|
||||
|
@ -184,6 +186,11 @@ public class FeaturedStickerSetInfoCell extends FrameLayout {
|
|||
animatorSet.cancel();
|
||||
animatorSet = null;
|
||||
}
|
||||
if (set != stickerSet) {
|
||||
unreadProgress = unread ? 1f : 0;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
set = stickerSet;
|
||||
stickerSetNameSearchIndex = index;
|
||||
stickerSetNameSearchLength = searchLength;
|
||||
|
@ -299,9 +306,24 @@ public class FeaturedStickerSetInfoCell extends FrameLayout {
|
|||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (isUnread) {
|
||||
if (isUnread || unreadProgress != 0f) {
|
||||
if (isUnread && unreadProgress != 1f) {
|
||||
unreadProgress += 16f / 100f;
|
||||
if (unreadProgress > 1f) {
|
||||
unreadProgress = 1f;
|
||||
} else {
|
||||
invalidate();
|
||||
}
|
||||
} else if (!isUnread && unreadProgress != 0) {
|
||||
unreadProgress -= 16f / 100f;
|
||||
if (unreadProgress < 0) {
|
||||
unreadProgress = 0;
|
||||
} else {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
paint.setColor(Theme.getColor(Theme.key_featuredStickers_unread));
|
||||
canvas.drawCircle(nameTextView.getRight() + AndroidUtilities.dp(12), AndroidUtilities.dp(20), AndroidUtilities.dp(4), paint);
|
||||
canvas.drawCircle(nameTextView.getRight() + AndroidUtilities.dp(12), AndroidUtilities.dp(20), AndroidUtilities.dp(4) * unreadProgress, paint);
|
||||
}
|
||||
if (needDivider) {
|
||||
canvas.drawLine(0, 0, getWidth(), 0, Theme.dividerPaint);
|
||||
|
|
|
@ -10,11 +10,11 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.FrameLayout;
|
||||
|
@ -50,7 +50,7 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
|
||||
private BackupImageView avatarImageView;
|
||||
private SimpleTextView nameTextView;
|
||||
private SimpleTextView[] statusTextView = new SimpleTextView[2];
|
||||
private SimpleTextView[] statusTextView = new SimpleTextView[3];
|
||||
private RLottieImageView muteButton;
|
||||
private RLottieDrawable muteDrawable;
|
||||
|
||||
|
@ -69,6 +69,7 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
|
||||
private boolean needDivider;
|
||||
private boolean currentIconGray;
|
||||
private int currentStatus;
|
||||
|
||||
private String grayIconColor = Theme.key_voipgroup_mutedIcon;
|
||||
|
||||
|
@ -81,6 +82,8 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
private boolean updateRunnableScheduled;
|
||||
private boolean isSpeaking;
|
||||
|
||||
private Drawable speakingDrawable;
|
||||
|
||||
private AnimatorSet animatorSet;
|
||||
|
||||
public GroupCallUserCell(Context context) {
|
||||
|
@ -102,32 +105,30 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
|
||||
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 54 : 67, 10, LocaleController.isRTL ? 67 : 54, 0));
|
||||
|
||||
for (int a = 0; a < 2; a++) {
|
||||
speakingDrawable = context.getResources().getDrawable(R.drawable.voice_volume_mini);
|
||||
speakingDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_voipgroup_speakingText), PorterDuff.Mode.MULTIPLY));
|
||||
|
||||
for (int a = 0; a < 3; a++) {
|
||||
statusTextView[a] = new SimpleTextView(context);
|
||||
statusTextView[a].setTextSize(15);
|
||||
statusTextView[a].setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
|
||||
if (a == 0) {
|
||||
statusTextView[a].setTextColor(Theme.getColor(Theme.key_voipgroup_listeningText));
|
||||
statusTextView[a].setText(LocaleController.getString("Listening", R.string.Listening));
|
||||
} else {
|
||||
} else if (a == 1) {
|
||||
statusTextView[a].setTextColor(Theme.getColor(Theme.key_voipgroup_speakingText));
|
||||
statusTextView[a].setText(LocaleController.getString("Speaking", R.string.Speaking));
|
||||
statusTextView[a].setDrawablePadding(AndroidUtilities.dp(2));
|
||||
} else {
|
||||
statusTextView[a].setTextColor(Theme.getColor(Theme.key_voipgroup_mutedByAdminIcon));
|
||||
statusTextView[a].setText(LocaleController.getString("VoipGroupMutedForMe", R.string.VoipGroupMutedForMe));
|
||||
}
|
||||
addView(statusTextView[a], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 54 : 67, 32, LocaleController.isRTL ? 67 : 54, 0));
|
||||
}
|
||||
|
||||
muteDrawable = new RLottieDrawable(R.raw.voice_outlined, "" + R.raw.voice_outlined, AndroidUtilities.dp(19), AndroidUtilities.dp(24), true, null);
|
||||
|
||||
muteButton = new RLottieImageView(context) {
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||
TLRPC.Chat chat = accountInstance.getMessagesController().getChat(currentCall.chatId);
|
||||
if (!ChatObject.canManageCalls(chat)) {
|
||||
return false;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
};
|
||||
muteButton = new RLottieImageView(context);
|
||||
muteButton.setScaleType(ImageView.ScaleType.CENTER);
|
||||
muteButton.setAnimation(muteDrawable);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
|
@ -251,28 +252,7 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
|
||||
private void applyParticipantChanges(boolean animated, boolean internal) {
|
||||
TLRPC.Chat chat = accountInstance.getMessagesController().getChat(currentCall.chatId);
|
||||
boolean canMute = ChatObject.canManageCalls(chat) && !isSelfUser();
|
||||
if (canMute) {
|
||||
boolean isAdmin = false;
|
||||
if (chat.megagroup) {
|
||||
isAdmin = accountInstance.getMessagesController().getAdminRank(currentCall.chatId, participant.user_id) != null;
|
||||
} else {
|
||||
TLRPC.ChatFull chatFull = accountInstance.getMessagesController().getChatFull(currentCall.chatId);
|
||||
if (chatFull != null) {
|
||||
for (int a = 0, N = chatFull.participants.participants.size(); a < N; a++) {
|
||||
TLRPC.ChatParticipant chatParticipant = chatFull.participants.participants.get(a);
|
||||
if (chatParticipant.user_id == participant.user_id) {
|
||||
isAdmin = chatParticipant instanceof TLRPC.TL_chatParticipantAdmin || chatParticipant instanceof TLRPC.TL_chatParticipantCreator;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isAdmin && participant.muted) {
|
||||
canMute = false;
|
||||
}
|
||||
}
|
||||
muteButton.setEnabled(canMute);
|
||||
muteButton.setEnabled(!isSelfUser());
|
||||
|
||||
if (!internal) {
|
||||
long diff = SystemClock.uptimeMillis() - participant.lastSpeakTime;
|
||||
|
@ -299,44 +279,44 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
ArrayList<Animator> animators = null;
|
||||
|
||||
boolean newMuted;
|
||||
boolean myted_by_me = participant.muted_by_you && !isSelfUser();
|
||||
if (isSelfUser()) {
|
||||
newMuted = VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().isMicMute() && (!isSpeaking || !participant.hasVoice);
|
||||
} else {
|
||||
newMuted = participant.muted && (!isSpeaking || !participant.hasVoice);
|
||||
newMuted = participant.muted && (!isSpeaking || !participant.hasVoice) || myted_by_me;
|
||||
}
|
||||
boolean newMutedByAdmin = newMuted && !participant.can_self_unmute;
|
||||
int newMuteColor;
|
||||
Object newTag;
|
||||
Object oldTag = statusTextView[0].getTag();
|
||||
int newStatus;
|
||||
currentIconGray = false;
|
||||
if (participant.muted && !isSpeaking) {
|
||||
if (!participant.can_self_unmute) {
|
||||
if (participant.muted && !isSpeaking || myted_by_me) {
|
||||
if (!participant.can_self_unmute || myted_by_me) {
|
||||
newMuteColor = Theme.getColor(Theme.key_voipgroup_mutedByAdminIcon);
|
||||
} else {
|
||||
newMuteColor = Theme.getColor(grayIconColor);
|
||||
currentIconGray = true;
|
||||
}
|
||||
newTag = null;
|
||||
newStatus = myted_by_me ? 2 : 0;
|
||||
} else {
|
||||
if (isSpeaking && participant.hasVoice) {
|
||||
newMuteColor = Theme.getColor(Theme.key_voipgroup_speakingText);
|
||||
newTag = 1;
|
||||
newStatus = 1;
|
||||
} else {
|
||||
newMuteColor = Theme.getColor(grayIconColor);
|
||||
newTag = null;
|
||||
newStatus = 0;
|
||||
currentIconGray = true;
|
||||
}
|
||||
}
|
||||
boolean somethingChanged = false;
|
||||
if (animatorSet != null) {
|
||||
if (newTag == null && oldTag != null || newTag != null && oldTag == null ||
|
||||
lastMuteColor != newMuteColor) {
|
||||
if (newStatus != currentStatus || lastMuteColor != newMuteColor) {
|
||||
somethingChanged = true;
|
||||
}
|
||||
}
|
||||
if (!animated || somethingChanged) {
|
||||
if (animatorSet != null) {
|
||||
animatorSet.cancel();
|
||||
animatorSet = null;
|
||||
}
|
||||
}
|
||||
if (!animated || lastMuteColor != newMuteColor || somethingChanged) {
|
||||
|
@ -359,64 +339,63 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
Theme.setSelectorDrawableColor(muteButton.getDrawable(), newMuteColor & 0x24ffffff, true);
|
||||
}
|
||||
}
|
||||
if (!animated || newTag == null && oldTag != null || newTag != null && oldTag == null || somethingChanged) {
|
||||
if (newStatus == 1) {
|
||||
int vol = ChatObject.getParticipantVolume(participant);
|
||||
int volume = vol / 100;
|
||||
if (volume != 100) {
|
||||
statusTextView[1].setLeftDrawable(speakingDrawable);
|
||||
statusTextView[1].setText((vol < 100 ? 1 : volume) + "% " + LocaleController.getString("Speaking", R.string.Speaking));
|
||||
} else {
|
||||
statusTextView[1].setLeftDrawable(null);
|
||||
statusTextView[1].setText(LocaleController.getString("Speaking", R.string.Speaking));
|
||||
}
|
||||
}
|
||||
if (!animated || newStatus != currentStatus || somethingChanged) {
|
||||
if (animated) {
|
||||
if (animators == null) {
|
||||
animators = new ArrayList<>();
|
||||
}
|
||||
statusTextView[0].setVisibility(VISIBLE);
|
||||
statusTextView[1].setVisibility(VISIBLE);
|
||||
if (newTag == null) {
|
||||
statusTextView[2].setVisibility(VISIBLE);
|
||||
if (newStatus == 0) {
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[0], View.TRANSLATION_Y, 0));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[0], View.ALPHA, 1.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[1], View.TRANSLATION_Y, -AndroidUtilities.dp(2)));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[1], View.ALPHA, 0.0f));
|
||||
} else {
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[2], View.TRANSLATION_Y, -AndroidUtilities.dp(2)));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[2], View.ALPHA, 0.0f));
|
||||
} else if (newStatus == 1) {
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[0], View.TRANSLATION_Y, AndroidUtilities.dp(2)));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[0], View.ALPHA, 0.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[1], View.TRANSLATION_Y, 0));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[1], View.ALPHA, 1.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[2], View.TRANSLATION_Y, -AndroidUtilities.dp(2)));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[2], View.ALPHA, 0.0f));
|
||||
} else {
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[0], View.TRANSLATION_Y, AndroidUtilities.dp(2)));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[0], View.ALPHA, 0.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[1], View.TRANSLATION_Y, -AndroidUtilities.dp(2)));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[1], View.ALPHA, 0.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[2], View.TRANSLATION_Y, 0));
|
||||
animators.add(ObjectAnimator.ofFloat(statusTextView[2], View.ALPHA, 1.0f));
|
||||
}
|
||||
} else {
|
||||
if (newTag == null) {
|
||||
statusTextView[0].setVisibility(VISIBLE);
|
||||
statusTextView[1].setVisibility(INVISIBLE);
|
||||
statusTextView[0].setTranslationY(0);
|
||||
statusTextView[0].setAlpha(1.0f);
|
||||
statusTextView[1].setTranslationY(-AndroidUtilities.dp(2));
|
||||
statusTextView[1].setAlpha(0.0f);
|
||||
} else {
|
||||
statusTextView[0].setVisibility(INVISIBLE);
|
||||
statusTextView[1].setVisibility(VISIBLE);
|
||||
statusTextView[0].setTranslationY(AndroidUtilities.dp(2));
|
||||
statusTextView[0].setAlpha(0.0f);
|
||||
statusTextView[1].setTranslationY(0);
|
||||
statusTextView[1].setAlpha(1.0f);
|
||||
}
|
||||
applyStatus(newStatus);
|
||||
}
|
||||
statusTextView[0].setTag(newTag);
|
||||
currentStatus = newStatus;
|
||||
}
|
||||
avatarWavesDrawable.setMuted(newTag == null, animated);
|
||||
avatarWavesDrawable.setMuted(newStatus, animated);
|
||||
if (animators != null) {
|
||||
if (animatorSet != null) {
|
||||
animatorSet.cancel();
|
||||
animatorSet = null;
|
||||
}
|
||||
animatorSet = new AnimatorSet();
|
||||
animatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (newTag == null) {
|
||||
statusTextView[0].setVisibility(VISIBLE);
|
||||
statusTextView[1].setVisibility(INVISIBLE);
|
||||
statusTextView[0].setTranslationY(0);
|
||||
statusTextView[0].setAlpha(1.0f);
|
||||
statusTextView[1].setTranslationY(-AndroidUtilities.dp(2));
|
||||
statusTextView[1].setAlpha(0.0f);
|
||||
} else {
|
||||
statusTextView[0].setVisibility(INVISIBLE);
|
||||
statusTextView[1].setVisibility(VISIBLE);
|
||||
statusTextView[0].setTranslationY(AndroidUtilities.dp(2));
|
||||
statusTextView[0].setAlpha(0.0f);
|
||||
statusTextView[1].setTranslationY(0);
|
||||
statusTextView[1].setAlpha(1.0f);
|
||||
}
|
||||
applyStatus(newStatus);
|
||||
animatorSet = null;
|
||||
}
|
||||
});
|
||||
|
@ -448,6 +427,40 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
avatarWavesDrawable.setShowWaves(isSpeaking, this);
|
||||
}
|
||||
|
||||
private void applyStatus(int newStatus) {
|
||||
if (newStatus == 0) {
|
||||
statusTextView[0].setVisibility(VISIBLE);
|
||||
statusTextView[0].setTranslationY(0);
|
||||
statusTextView[0].setAlpha(1.0f);
|
||||
statusTextView[1].setVisibility(INVISIBLE);
|
||||
statusTextView[1].setTranslationY(-AndroidUtilities.dp(2));
|
||||
statusTextView[1].setAlpha(0.0f);
|
||||
statusTextView[2].setVisibility(INVISIBLE);
|
||||
statusTextView[2].setTranslationY(-AndroidUtilities.dp(2));
|
||||
statusTextView[2].setAlpha(0.0f);
|
||||
} else if (newStatus == 1) {
|
||||
statusTextView[0].setVisibility(INVISIBLE);
|
||||
statusTextView[0].setTranslationY(AndroidUtilities.dp(2));
|
||||
statusTextView[0].setAlpha(0.0f);
|
||||
statusTextView[1].setVisibility(VISIBLE);
|
||||
statusTextView[1].setTranslationY(0);
|
||||
statusTextView[1].setAlpha(1.0f);
|
||||
statusTextView[2].setVisibility(INVISIBLE);
|
||||
statusTextView[2].setTranslationY(-AndroidUtilities.dp(2));
|
||||
statusTextView[2].setAlpha(0.0f);
|
||||
} else {
|
||||
statusTextView[0].setVisibility(INVISIBLE);
|
||||
statusTextView[0].setTranslationY(AndroidUtilities.dp(2));
|
||||
statusTextView[0].setAlpha(0.0f);
|
||||
statusTextView[1].setVisibility(INVISIBLE);
|
||||
statusTextView[1].setTranslationY(-AndroidUtilities.dp(2));
|
||||
statusTextView[1].setAlpha(0.0f);
|
||||
statusTextView[2].setVisibility(VISIBLE);
|
||||
statusTextView[2].setTranslationY(0);
|
||||
statusTextView[2].setAlpha(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
|
@ -481,7 +494,7 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
private BlobDrawable blobDrawable2;
|
||||
|
||||
private boolean hasCustomColor;
|
||||
private boolean isMuted;
|
||||
private int isMuted;
|
||||
private float progressToMuted = 0;
|
||||
|
||||
boolean invalidateColor = true;
|
||||
|
@ -535,13 +548,13 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
canvas.scale(scaleBlob * wavesEnter, scaleBlob * wavesEnter, cx, cy);
|
||||
|
||||
if (!hasCustomColor) {
|
||||
if (isMuted && progressToMuted != 1f) {
|
||||
if (isMuted != 1 && progressToMuted != 1f) {
|
||||
progressToMuted += 16 / 150f;
|
||||
if (progressToMuted > 1f) {
|
||||
progressToMuted = 1f;
|
||||
}
|
||||
invalidateColor = true;
|
||||
} else if (!isMuted && progressToMuted != 0f) {
|
||||
} else if (isMuted == 1 && progressToMuted != 0f) {
|
||||
progressToMuted -= 16 / 150f;
|
||||
if (progressToMuted < 0f) {
|
||||
progressToMuted = 0f;
|
||||
|
@ -550,7 +563,7 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
}
|
||||
|
||||
if (invalidateColor) {
|
||||
int color = ColorUtils.blendARGB(Theme.getColor(Theme.key_voipgroup_speakingText), Theme.getColor(Theme.key_voipgroup_listeningText), progressToMuted);
|
||||
int color = ColorUtils.blendARGB(Theme.getColor(Theme.key_voipgroup_speakingText), isMuted == 2 ? Theme.getColor(Theme.key_voipgroup_mutedByAdminIcon) : Theme.getColor(Theme.key_voipgroup_listeningText), progressToMuted);
|
||||
blobDrawable.paint.setColor(ColorUtils.setAlphaComponent(color, (int) (255 * WaveDrawable.CIRCLE_ALPHA_2)));
|
||||
}
|
||||
}
|
||||
|
@ -575,9 +588,9 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
return scaleAvatar * wavesEnter + 1f * (1f - wavesEnter);
|
||||
}
|
||||
|
||||
public void setShowWaves(boolean show, View parenView) {
|
||||
public void setShowWaves(boolean show, View parentView) {
|
||||
if (showWaves != show) {
|
||||
parenView.invalidate();
|
||||
parentView.invalidate();
|
||||
}
|
||||
showWaves = show;
|
||||
}
|
||||
|
@ -601,10 +614,10 @@ public class GroupCallUserCell extends FrameLayout {
|
|||
blobDrawable.paint.setColor(color);
|
||||
}
|
||||
|
||||
public void setMuted(boolean isMuted, boolean animated) {
|
||||
this.isMuted = isMuted;
|
||||
public void setMuted(int status, boolean animated) {
|
||||
this.isMuted = status;
|
||||
if (!animated) {
|
||||
progressToMuted = isMuted ? 1f : 0f;
|
||||
progressToMuted = isMuted != 1 ? 1f : 0f;
|
||||
}
|
||||
invalidateColor = true;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.telegram.tgnet.TLRPC;
|
|||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.AvatarDrawable;
|
||||
import org.telegram.ui.Components.BackupImageView;
|
||||
import org.telegram.ui.Components.CounterView;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
|
||||
public class HintDialogCell extends FrameLayout {
|
||||
|
@ -40,12 +41,14 @@ public class HintDialogCell extends FrameLayout {
|
|||
private RectF rect = new RectF();
|
||||
|
||||
private int lastUnreadCount;
|
||||
private int countWidth;
|
||||
private StaticLayout countLayout;
|
||||
private TLRPC.User currentUser;
|
||||
|
||||
private long dialog_id;
|
||||
private int currentAccount = UserConfig.selectedAccount;
|
||||
float showOnlineProgress;
|
||||
boolean wasDraw;
|
||||
|
||||
CounterView counterView;
|
||||
|
||||
public HintDialogCell(Context context) {
|
||||
super(context);
|
||||
|
@ -62,11 +65,17 @@ public class HintDialogCell extends FrameLayout {
|
|||
nameTextView.setLines(1);
|
||||
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 6, 64, 6, 0));
|
||||
|
||||
counterView = new CounterView(context);
|
||||
addView(counterView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 28, Gravity.TOP,0 ,4,0,0));
|
||||
counterView.setColors(Theme.key_chats_unreadCounterText, Theme.key_chats_unreadCounter);
|
||||
counterView.setGravity(Gravity.RIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY));
|
||||
counterView.horizontalPadding = AndroidUtilities.dp(13);
|
||||
}
|
||||
|
||||
public void update(int mask) {
|
||||
|
@ -84,19 +93,11 @@ public class HintDialogCell extends FrameLayout {
|
|||
if (dialog != null && dialog.unread_count != 0) {
|
||||
if (lastUnreadCount != dialog.unread_count) {
|
||||
lastUnreadCount = dialog.unread_count;
|
||||
String countString = String.format("%d", dialog.unread_count);
|
||||
countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(Theme.dialogs_countTextPaint.measureText(countString)));
|
||||
countLayout = new StaticLayout(countString, Theme.dialogs_countTextPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
|
||||
if (mask != 0) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
} else if (countLayout != null) {
|
||||
if (mask != 0) {
|
||||
invalidate();
|
||||
counterView.setCount(lastUnreadCount, wasDraw);
|
||||
}
|
||||
} else {
|
||||
lastUnreadCount = 0;
|
||||
countLayout = null;
|
||||
counterView.setCount(0, wasDraw);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,6 +115,10 @@ public class HintDialogCell extends FrameLayout {
|
|||
}
|
||||
|
||||
public void setDialog(int uid, boolean counter, CharSequence name) {
|
||||
if (dialog_id != uid) {
|
||||
wasDraw = false;
|
||||
invalidate();
|
||||
}
|
||||
dialog_id = uid;
|
||||
if (uid > 0) {
|
||||
currentUser = MessagesController.getInstance(currentAccount).getUser(uid);
|
||||
|
@ -141,8 +146,6 @@ public class HintDialogCell extends FrameLayout {
|
|||
}
|
||||
if (counter) {
|
||||
update(0);
|
||||
} else {
|
||||
countLayout = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,25 +153,35 @@ public class HintDialogCell extends FrameLayout {
|
|||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
boolean result = super.drawChild(canvas, child, drawingTime);
|
||||
if (child == imageView) {
|
||||
if (countLayout != null) {
|
||||
int top = AndroidUtilities.dp(6);
|
||||
int left = AndroidUtilities.dp(54);
|
||||
int x = left - AndroidUtilities.dp(5.5f);
|
||||
rect.set(x, top, x + countWidth + AndroidUtilities.dp(11), top + AndroidUtilities.dp(23));
|
||||
canvas.drawRoundRect(rect, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, MessagesController.getInstance(currentAccount).isDialogMuted(dialog_id) ? Theme.dialogs_countGrayPaint : Theme.dialogs_countPaint);
|
||||
canvas.save();
|
||||
canvas.translate(left, top + AndroidUtilities.dp(4));
|
||||
countLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
boolean showOnline = currentUser != null && !currentUser.bot && (currentUser.status != null && currentUser.status.expires > ConnectionsManager.getInstance(currentAccount).getCurrentTime() || MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(currentUser.id));
|
||||
if (!wasDraw) {
|
||||
showOnlineProgress = showOnline ? 1f : 0f;
|
||||
}
|
||||
if (currentUser != null && !currentUser.bot && (currentUser.status != null && currentUser.status.expires > ConnectionsManager.getInstance(currentAccount).getCurrentTime() || MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(currentUser.id))) {
|
||||
if (showOnline && showOnlineProgress != 1f) {
|
||||
showOnlineProgress += 16f / 150;
|
||||
if (showOnlineProgress > 1) {
|
||||
showOnlineProgress = 1f;
|
||||
}
|
||||
invalidate();
|
||||
} else if (!showOnline && showOnlineProgress != 0) {
|
||||
showOnlineProgress -= 16f / 150;
|
||||
if (showOnlineProgress < 0) {
|
||||
showOnlineProgress = 0;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
if (showOnlineProgress != 0) {
|
||||
int top = AndroidUtilities.dp(53);
|
||||
int left = AndroidUtilities.dp(59);
|
||||
canvas.save();
|
||||
canvas.scale(showOnlineProgress, showOnlineProgress, left, top);
|
||||
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite));
|
||||
canvas.drawCircle(left, top, AndroidUtilities.dp(7), Theme.dialogs_onlineCirclePaint);
|
||||
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(Theme.key_chats_onlineCircle));
|
||||
canvas.drawCircle(left, top, AndroidUtilities.dp(5), Theme.dialogs_onlineCirclePaint);
|
||||
canvas.restore();
|
||||
}
|
||||
wasDraw = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.telegram.messenger.UserConfig;
|
|||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.CheckBox2;
|
||||
import org.telegram.ui.Components.DotDividerSpan;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.MediaActionDrawable;
|
||||
import org.telegram.ui.Components.RadialProgress2;
|
||||
|
@ -109,25 +110,7 @@ public class SharedAudioCell extends FrameLayout implements DownloadController.F
|
|||
description2TextPaint.setTextSize(AndroidUtilities.dp(13));
|
||||
|
||||
dotSpan = new SpannableStringBuilder(".");
|
||||
dotSpan.setSpan(new ReplacementSpan() {
|
||||
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
int color;
|
||||
|
||||
@Override
|
||||
public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) {
|
||||
return AndroidUtilities.dp(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
|
||||
if (color != paint.getColor()) {
|
||||
p.setColor(paint.getColor());
|
||||
}
|
||||
float radius = AndroidUtilities.dpf2(3) / 2f;
|
||||
canvas.drawCircle(x + radius, (bottom - top) / 2, radius, p);
|
||||
}
|
||||
}, 0, 1, 0);
|
||||
dotSpan.setSpan(new DotDividerSpan(), 0, 1, 0);
|
||||
}
|
||||
|
||||
captionTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
|
|
@ -8,18 +8,29 @@
|
|||
|
||||
package org.telegram.ui.Cells;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.ReplacementSpan;
|
||||
import android.transition.ChangeBounds;
|
||||
import android.transition.Fade;
|
||||
import android.transition.TransitionManager;
|
||||
import android.transition.TransitionSet;
|
||||
import android.transition.TransitionValues;
|
||||
import android.transition.Visibility;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
@ -40,11 +51,16 @@ import org.telegram.messenger.FileLoader;
|
|||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.ActionBarMenuItem;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.BackupImageView;
|
||||
import org.telegram.ui.Components.CheckBox2;
|
||||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||
import org.telegram.ui.Components.DotDividerSpan;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.LineProgressView;
|
||||
import org.telegram.ui.Components.RLottieDrawable;
|
||||
import org.telegram.ui.Components.RLottieImageView;
|
||||
import org.telegram.ui.FilteredSearchView;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -58,7 +74,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
private TextView nameTextView;
|
||||
private TextView extTextView;
|
||||
private TextView dateTextView;
|
||||
private ImageView statusImageView;
|
||||
private RLottieImageView statusImageView;
|
||||
private LineProgressView progressView;
|
||||
private CheckBox2 checkBox;
|
||||
private TextView rightDateTextView;
|
||||
|
@ -81,6 +97,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
|
||||
private SpannableStringBuilder dotSpan;
|
||||
private CharSequence caption;
|
||||
private RLottieDrawable statusDrawable;
|
||||
|
||||
public SharedDocumentCell(Context context) {
|
||||
this(context, VIEW_TYPE_DEFAULT);
|
||||
|
@ -181,13 +198,15 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 5, LocaleController.isRTL ? 72 : 8, 0));
|
||||
}
|
||||
|
||||
statusImageView = new ImageView(context);
|
||||
statusDrawable = new RLottieDrawable(R.raw.download_arrow, "download_arrow", AndroidUtilities.dp(14), AndroidUtilities.dp(14), true, null);
|
||||
statusImageView = new RLottieImageView(context);
|
||||
statusImageView.setAnimation(statusDrawable);
|
||||
statusImageView.setVisibility(INVISIBLE);
|
||||
statusImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_sharedMedia_startStopLoadIcon), PorterDuff.Mode.MULTIPLY));
|
||||
if (viewType == VIEW_TYPE_PICKER) {
|
||||
addView(statusImageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 39, LocaleController.isRTL ? 72 : 8, 0));
|
||||
addView(statusImageView, LayoutHelper.createFrame(14, 14, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 70, 37, LocaleController.isRTL ? 72 : 8, 0));
|
||||
} else {
|
||||
addView(statusImageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 35, LocaleController.isRTL ? 72 : 8, 0));
|
||||
addView(statusImageView, LayoutHelper.createFrame(14, 14, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 70, 33, LocaleController.isRTL ? 72 : 8, 0));
|
||||
}
|
||||
|
||||
dateTextView = new TextView(context);
|
||||
|
@ -222,25 +241,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
|
||||
if (viewType == VIEW_TYPE_GLOBAL_SEARCH) {
|
||||
dotSpan = new SpannableStringBuilder(".");
|
||||
dotSpan.setSpan(new ReplacementSpan() {
|
||||
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
int color;
|
||||
|
||||
@Override
|
||||
public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) {
|
||||
return AndroidUtilities.dp(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
|
||||
if (color != paint.getColor()) {
|
||||
p.setColor(paint.getColor());
|
||||
}
|
||||
float radius = AndroidUtilities.dpf2(3) / 2f;
|
||||
canvas.drawCircle(x + radius, (bottom - top) / 2, radius, p);
|
||||
}
|
||||
}, 0, 1, 0);
|
||||
dotSpan.setSpan(new DotDividerSpan(), 0, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,7 +360,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (progressView.getVisibility() == VISIBLE) {
|
||||
updateFileExistIcon();
|
||||
updateFileExistIcon(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,6 +372,7 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
}
|
||||
|
||||
public void setDocument(MessageObject messageObject, boolean divider) {
|
||||
boolean animated = message != null && messageObject != null && message.getId() != messageObject.getId();
|
||||
needDivider = divider;
|
||||
message = messageObject;
|
||||
loaded = false;
|
||||
|
@ -463,16 +465,31 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
|
||||
setWillNotDraw(!needDivider);
|
||||
progressView.setProgress(0, false);
|
||||
updateFileExistIcon();
|
||||
updateFileExistIcon(animated);
|
||||
}
|
||||
|
||||
public void updateFileExistIcon() {
|
||||
public void updateFileExistIcon(boolean animated) {
|
||||
if (animated && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
TransitionSet transition = new TransitionSet();
|
||||
ChangeBounds changeBounds = new ChangeBounds();
|
||||
changeBounds.setDuration(150);
|
||||
transition.addTransition(new Fade().setDuration(150)).addTransition(changeBounds);
|
||||
transition.setOrdering(TransitionSet.ORDERING_TOGETHER);
|
||||
transition.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
TransitionManager.beginDelayedTransition(this, transition);
|
||||
}
|
||||
if (message != null && message.messageOwner.media != null) {
|
||||
loaded = false;
|
||||
if (message.attachPathExists || message.mediaExists) {
|
||||
statusImageView.setVisibility(INVISIBLE);
|
||||
progressView.setVisibility(INVISIBLE);
|
||||
dateTextView.setPadding(0, 0, 0, 0);
|
||||
|
||||
LayoutParams layoutParams = (LayoutParams) dateTextView.getLayoutParams();
|
||||
if (layoutParams != null) {
|
||||
layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 8 : 72);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 72 : 8);
|
||||
dateTextView.requestLayout();
|
||||
}
|
||||
loading = false;
|
||||
loaded = true;
|
||||
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
|
||||
|
@ -481,8 +498,20 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, message, this);
|
||||
loading = FileLoader.getInstance(currentAccount).isLoadingFile(fileName);
|
||||
statusImageView.setVisibility(VISIBLE);
|
||||
statusImageView.setImageResource(loading ? R.drawable.media_doc_pause : R.drawable.media_doc_load);
|
||||
dateTextView.setPadding(LocaleController.isRTL ? 0 : AndroidUtilities.dp(14), 0, LocaleController.isRTL ? AndroidUtilities.dp(14) : 0, 0);
|
||||
statusDrawable.setCustomEndFrame(loading ? 15 : 0);
|
||||
statusDrawable.setPlayInDirectionOfCustomEndFrame(true);
|
||||
if (animated) {
|
||||
statusImageView.playAnimation();
|
||||
} else {
|
||||
statusDrawable.setCurrentFrame(loading ? 15 : 0);
|
||||
statusImageView.invalidate();
|
||||
}
|
||||
LayoutParams layoutParams = (LayoutParams) dateTextView.getLayoutParams();
|
||||
if (layoutParams != null) {
|
||||
layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 8 : (72 + 14));
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? (72 + 14) : 8);
|
||||
dateTextView.requestLayout();
|
||||
}
|
||||
if (loading) {
|
||||
progressView.setVisibility(VISIBLE);
|
||||
Float progress = ImageLoader.getInstance().getFileProgress(fileName);
|
||||
|
@ -500,7 +529,12 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
progressView.setVisibility(INVISIBLE);
|
||||
progressView.setProgress(0, false);
|
||||
statusImageView.setVisibility(INVISIBLE);
|
||||
dateTextView.setPadding(0, 0, 0, 0);
|
||||
LayoutParams layoutParams = (LayoutParams) dateTextView.getLayoutParams();
|
||||
if (layoutParams != null) {
|
||||
layoutParams.leftMargin = AndroidUtilities.dp(LocaleController.isRTL ? 8 : 72);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(LocaleController.isRTL ? 72 : 8);
|
||||
dateTextView.requestLayout();
|
||||
}
|
||||
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
|
||||
}
|
||||
}
|
||||
|
@ -572,19 +606,19 @@ public class SharedDocumentCell extends FrameLayout implements DownloadControlle
|
|||
|
||||
@Override
|
||||
public void onFailedDownload(String name, boolean canceled) {
|
||||
updateFileExistIcon();
|
||||
updateFileExistIcon(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccessDownload(String name) {
|
||||
progressView.setProgress(1, true);
|
||||
updateFileExistIcon();
|
||||
updateFileExistIcon(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressDownload(String fileName, long downloadedSize, long totalSize) {
|
||||
if (progressView.getVisibility() != VISIBLE) {
|
||||
updateFileExistIcon();
|
||||
updateFileExistIcon(true);
|
||||
}
|
||||
progressView.setProgress(Math.min(1f, downloadedSize / (float) totalSize), true);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ public class TextCell extends FrameLayout {
|
|||
private boolean needDivider;
|
||||
private int offsetFromImage = 71;
|
||||
private int imageLeft = 21;
|
||||
private boolean inDialogs;
|
||||
|
||||
public TextCell(Context context) {
|
||||
this(context, 23, false);
|
||||
|
@ -70,6 +71,10 @@ public class TextCell extends FrameLayout {
|
|||
setFocusable(true);
|
||||
}
|
||||
|
||||
public void setIsInDialogs() {
|
||||
inDialogs = true;
|
||||
}
|
||||
|
||||
public SimpleTextView getTextView() {
|
||||
return textView;
|
||||
}
|
||||
|
@ -219,7 +224,7 @@ public class TextCell extends FrameLayout {
|
|||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (needDivider) {
|
||||
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? 68 : 20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? 68 : 20) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
|
||||
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? (inDialogs ? 72 : 68) : 20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? (inDialogs ? 72 : 68) : 20) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ package org.telegram.ui.Cells;
|
|||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
|
@ -45,7 +46,13 @@ public class TextInfoPrivacyCell extends FrameLayout {
|
|||
public TextInfoPrivacyCell(Context context, int padding) {
|
||||
super(context);
|
||||
|
||||
textView = new TextView(context);
|
||||
textView = new TextView(context) {
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
onTextDraw();
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
};
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
textView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
|
||||
textView.setPadding(0, AndroidUtilities.dp(10), 0, AndroidUtilities.dp(17));
|
||||
|
@ -56,6 +63,10 @@ public class TextInfoPrivacyCell extends FrameLayout {
|
|||
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, padding, 0, padding, 0));
|
||||
}
|
||||
|
||||
protected void onTextDraw() {
|
||||
|
||||
}
|
||||
|
||||
public void setLinkTextColorKey(String key) {
|
||||
linkTextColorKey = key;
|
||||
}
|
||||
|
|
|
@ -499,6 +499,11 @@ public class UserCell extends FrameLayout {
|
|||
} else {
|
||||
avatarImageView.setImageDrawable(avatarDrawable);
|
||||
}
|
||||
|
||||
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
|
||||
if (adminTextView != null) {
|
||||
adminTextView.setTextColor(Theme.getColor(Theme.key_profile_creatorIcon));
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelfAsSavedMessages(boolean value) {
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.os.Vibrator;
|
|||
import android.text.Editable;
|
||||
import android.text.InputFilter;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
|
@ -35,7 +36,6 @@ import android.widget.ScrollView;
|
|||
import android.widget.TextView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ApplicationLoader;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.ImageLocation;
|
||||
|
@ -59,12 +59,14 @@ import org.telegram.ui.Cells.ShadowSectionCell;
|
|||
import org.telegram.ui.Cells.TextBlockCell;
|
||||
import org.telegram.ui.Cells.TextInfoPrivacyCell;
|
||||
import org.telegram.ui.Components.AvatarDrawable;
|
||||
import org.telegram.ui.Components.BulletinFactory;
|
||||
import org.telegram.ui.Components.EditTextEmoji;
|
||||
import org.telegram.ui.Components.ImageUpdater;
|
||||
import org.telegram.ui.Components.BackupImageView;
|
||||
import org.telegram.ui.Components.EditTextBoldCursor;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.LinkActionView;
|
||||
import org.telegram.ui.Components.RLottieDrawable;
|
||||
import org.telegram.ui.Components.RLottieImageView;
|
||||
import org.telegram.ui.Components.RadialProgressView;
|
||||
import org.telegram.ui.Components.SizeNotifierFrameLayout;
|
||||
|
||||
|
@ -78,7 +80,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
private ShadowSectionCell sectionCell;
|
||||
private BackupImageView avatarImage;
|
||||
private View avatarOverlay;
|
||||
private ImageView avatarEditor;
|
||||
private RLottieImageView avatarEditor;
|
||||
private AnimatorSet avatarAnimation;
|
||||
private RadialProgressView avatarProgressView;
|
||||
private AvatarDrawable avatarDrawable;
|
||||
|
@ -91,11 +93,14 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
private HeaderCell headerCell2;
|
||||
private EditTextBoldCursor editText;
|
||||
|
||||
private RLottieDrawable cameraDrawable;
|
||||
|
||||
private LinearLayout linearLayout;
|
||||
private LinearLayout adminnedChannelsLayout;
|
||||
private LinearLayout linkContainer;
|
||||
private LinearLayout publicContainer;
|
||||
private TextBlockCell privateContainer;
|
||||
private LinearLayout privateContainer;
|
||||
private LinkActionView permanentLinkView;
|
||||
private RadioButtonCell radioButtonCell1;
|
||||
private RadioButtonCell radioButtonCell2;
|
||||
private TextInfoPrivacyCell typeInfoCell;
|
||||
|
@ -108,7 +113,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
private boolean lastNameAvailable;
|
||||
private boolean isPrivate;
|
||||
private boolean loadingInvite;
|
||||
private TLRPC.ExportedChatInvite invite;
|
||||
private TLRPC.TL_chatInviteExported invite;
|
||||
|
||||
private boolean loadingAdminedChannels;
|
||||
private TextInfoPrivacyCell adminedInfoCell;
|
||||
|
@ -270,7 +275,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
progressDialog.show();
|
||||
return;
|
||||
}
|
||||
final int reqId = MessagesController.getInstance(currentAccount).createChat(nameTextView.getText().toString(), new ArrayList<>(), descriptionTextView.getText().toString(), ChatObject.CHAT_TYPE_CHANNEL, null, null, ChannelCreateActivity.this);
|
||||
final int reqId = MessagesController.getInstance(currentAccount).createChat(nameTextView.getText().toString(), new ArrayList<>(), descriptionTextView.getText().toString(), ChatObject.CHAT_TYPE_CHANNEL, false, null, null, ChannelCreateActivity.this);
|
||||
progressDialog = new AlertDialog(getParentActivity(), 3);
|
||||
progressDialog.setOnCancelListener(dialog -> {
|
||||
ConnectionsManager.getInstance(currentAccount).cancelRequest(reqId, true);
|
||||
|
@ -481,18 +486,30 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
}
|
||||
};
|
||||
frameLayout.addView(avatarOverlay, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 16, 12, LocaleController.isRTL ? 16 : 0, 12));
|
||||
avatarOverlay.setOnClickListener(view -> imageUpdater.openMenu(avatar != null, () -> {
|
||||
avatar = null;
|
||||
avatarBig = null;
|
||||
inputPhoto = null;
|
||||
inputVideo = null;
|
||||
inputVideoPath = null;
|
||||
videoTimestamp = 0;
|
||||
showAvatarProgress(false, true);
|
||||
avatarImage.setImage(null, null, avatarDrawable, null);
|
||||
}));
|
||||
avatarOverlay.setOnClickListener(view -> {
|
||||
imageUpdater.openMenu(avatar != null, () -> {
|
||||
avatar = null;
|
||||
avatarBig = null;
|
||||
inputPhoto = null;
|
||||
inputVideo = null;
|
||||
inputVideoPath = null;
|
||||
videoTimestamp = 0;
|
||||
showAvatarProgress(false, true);
|
||||
avatarImage.setImage(null, null, avatarDrawable, null);
|
||||
avatarEditor.setAnimation(cameraDrawable);
|
||||
cameraDrawable.setCurrentFrame(0);
|
||||
}, dialog -> {
|
||||
cameraDrawable.setCustomEndFrame(86);
|
||||
avatarEditor.playAnimation();
|
||||
});
|
||||
cameraDrawable.setCurrentFrame(0);
|
||||
cameraDrawable.setCustomEndFrame(43);
|
||||
avatarEditor.playAnimation();
|
||||
});
|
||||
|
||||
avatarEditor = new ImageView(context) {
|
||||
cameraDrawable = new RLottieDrawable(R.raw.camera, "" + R.raw.camera, AndroidUtilities.dp(60), AndroidUtilities.dp(60), false, null);
|
||||
|
||||
avatarEditor = new RLottieImageView(context) {
|
||||
@Override
|
||||
public void invalidate(int l, int t, int r, int b) {
|
||||
super.invalidate(l, t, r, b);
|
||||
|
@ -506,9 +523,10 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
}
|
||||
};
|
||||
avatarEditor.setScaleType(ImageView.ScaleType.CENTER);
|
||||
avatarEditor.setImageResource(R.drawable.menu_camera_av);
|
||||
avatarEditor.setAnimation(cameraDrawable);
|
||||
avatarEditor.setEnabled(false);
|
||||
avatarEditor.setClickable(false);
|
||||
avatarEditor.setPadding(AndroidUtilities.dp(2), 0, 0, AndroidUtilities.dp(1));
|
||||
frameLayout.addView(avatarEditor, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 16, 12, LocaleController.isRTL ? 16 : 0, 12));
|
||||
|
||||
avatarProgressView = new RadialProgressView(context);
|
||||
|
@ -528,6 +546,15 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
InputFilter[] inputFilters = new InputFilter[1];
|
||||
inputFilters[0] = new InputFilter.LengthFilter(100);
|
||||
nameTextView.setFilters(inputFilters);
|
||||
nameTextView.getEditText().setSingleLine(true);
|
||||
nameTextView.getEditText().setImeOptions(EditorInfo.IME_ACTION_NEXT);
|
||||
nameTextView.getEditText().setOnEditorActionListener((textView, i, keyEvent) -> {
|
||||
if (i == EditorInfo.IME_ACTION_NEXT && !TextUtils.isEmpty(nameTextView.getEditText().getText())) {
|
||||
descriptionTextView.requestFocus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
frameLayout.addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, LocaleController.isRTL ? 5 : 96, 0, LocaleController.isRTL ? 96 : 5, 0));
|
||||
|
||||
descriptionTextView = new EditTextBoldCursor(context);
|
||||
|
@ -687,24 +714,14 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
}
|
||||
});
|
||||
|
||||
privateContainer = new TextBlockCell(context);
|
||||
privateContainer.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
linkContainer.addView(privateContainer);
|
||||
privateContainer.setOnClickListener(v -> {
|
||||
if (invite == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
android.content.ClipData clip = android.content.ClipData.newPlainText("label", invite.link);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
if (BulletinFactory.canShowBulletin(ChannelCreateActivity.this)) {
|
||||
BulletinFactory.createCopyLinkBulletin(ChannelCreateActivity.this).show();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
privateContainer = new LinearLayout(context);
|
||||
privateContainer.setOrientation(LinearLayout.VERTICAL);
|
||||
linkContainer.addView(privateContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
permanentLinkView = new LinkActionView(context, this, null, chatId, true);
|
||||
permanentLinkView.showOptions(false);
|
||||
permanentLinkView.setUsers(0, null);
|
||||
privateContainer.addView(permanentLinkView);
|
||||
|
||||
checkTextView = new TextView(context);
|
||||
checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
|
@ -739,14 +756,18 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
return;
|
||||
}
|
||||
loadingInvite = true;
|
||||
TLRPC.TL_messages_exportChatInvite req = new TLRPC.TL_messages_exportChatInvite();
|
||||
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(-chatId);
|
||||
TLRPC.TL_messages_getExportedChatInvites req = new TLRPC.TL_messages_getExportedChatInvites();
|
||||
req.peer = getMessagesController().getInputPeer(-chatId);
|
||||
req.admin_id = getMessagesController().getInputUser(getUserConfig().getCurrentUser());
|
||||
req.limit = 1;
|
||||
|
||||
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
if (error == null) {
|
||||
invite = (TLRPC.ExportedChatInvite) response;
|
||||
TLRPC.TL_messages_exportedChatInvites invites = (TLRPC.TL_messages_exportedChatInvites) response;
|
||||
invite = (TLRPC.TL_chatInviteExported) invites.invites.get(0);
|
||||
}
|
||||
loadingInvite = false;
|
||||
privateContainer.setText(invite != null ? invite.link : LocaleController.getString("Loading", R.string.Loading), false);
|
||||
permanentLinkView.setLink(invite != null ? invite.link : null);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -785,7 +806,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
publicContainer.setVisibility(isPrivate ? View.GONE : View.VISIBLE);
|
||||
privateContainer.setVisibility(isPrivate ? View.VISIBLE : View.GONE);
|
||||
linkContainer.setPadding(0, 0, 0, isPrivate ? 0 : AndroidUtilities.dp(7));
|
||||
privateContainer.setText(invite != null ? invite.link : LocaleController.getString("Loading", R.string.Loading), false);
|
||||
permanentLinkView.setLink(invite != null ? invite.link : null);
|
||||
checkTextView.setVisibility(!isPrivate && checkTextView.length() != 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
radioButtonCell1.setChecked(!isPrivate, true);
|
||||
|
@ -917,7 +938,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
|
|||
}
|
||||
if (nameTextView != null) {
|
||||
String text = nameTextView.getText().toString();
|
||||
if (text != null && text.length() != 0) {
|
||||
if (text.length() != 0) {
|
||||
args.putString("nameTextView", text);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,9 +172,11 @@ import org.telegram.ui.Components.ChatAttachAlertDocumentLayout;
|
|||
import org.telegram.ui.Components.ChatAvatarContainer;
|
||||
import org.telegram.ui.Components.ChatBigEmptyView;
|
||||
import org.telegram.ui.Components.ChatGreetingsView;
|
||||
import org.telegram.ui.Components.ChecksHintView;
|
||||
import org.telegram.ui.Components.ClippingImageView;
|
||||
import org.telegram.ui.Components.CombinedDrawable;
|
||||
import org.telegram.ui.Components.CorrectlyMeasuringTextView;
|
||||
import org.telegram.ui.Components.CounterView;
|
||||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||
import org.telegram.ui.Components.EditTextBoldCursor;
|
||||
import org.telegram.ui.Components.EditTextCaption;
|
||||
|
@ -184,7 +186,9 @@ import org.telegram.ui.Components.ExtendedGridLayoutManager;
|
|||
import org.telegram.ui.Components.FireworksOverlay;
|
||||
import org.telegram.ui.Components.FragmentContextView;
|
||||
import org.telegram.ui.Components.HintView;
|
||||
import org.telegram.ui.Components.ImportingAlert;
|
||||
import org.telegram.ui.Components.InstantCameraView;
|
||||
import org.telegram.ui.Components.InviteMembersBottomSheet;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.MessageBackgroundDrawable;
|
||||
import org.telegram.ui.Components.NumberTextView;
|
||||
|
@ -287,7 +291,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
private FrameLayout pagedownButton;
|
||||
private ImageView pagedownButtonImage;
|
||||
private boolean pagedownButtonShowedByScroll;
|
||||
private SimpleTextView pagedownButtonCounter;
|
||||
private CounterView pagedownButtonCounter;
|
||||
private FrameLayout mentiondownButton;
|
||||
private SimpleTextView mentiondownButtonCounter;
|
||||
private ImageView mentiondownButtonImage;
|
||||
|
@ -326,6 +330,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
private TextView voiceHintTextView;
|
||||
private HintView noSoundHintView;
|
||||
private HintView forwardHintView;
|
||||
private ChecksHintView checksHintView;
|
||||
private Runnable voiceHintHideRunnable;
|
||||
private AnimatorSet voiceHintAnimation;
|
||||
private View emojiButtonRed;
|
||||
|
@ -636,6 +641,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
private int distanceToPeer;
|
||||
|
||||
private boolean openImport;
|
||||
|
||||
private float chatListViewPaddingTop;
|
||||
private int chatListViewPaddingVisibleOffset;
|
||||
|
||||
|
@ -645,7 +652,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
private float topChatPanelViewOffset;
|
||||
private float pinnedMessageEnterOffset;
|
||||
private float topViewOffset;
|
||||
protected TLRPC.Document preloadedGreetingsSticker;
|
||||
private TLRPC.Document preloadedGreetingsSticker;
|
||||
private boolean forceHistoryEmpty;
|
||||
private float bottomPanelTranslationY;
|
||||
private boolean invalidateChatListViewTopPadding;
|
||||
private long activityResumeTime;
|
||||
|
@ -667,7 +675,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
NotificationCenter.didUpdateConnectionState,
|
||||
NotificationCenter.updateInterfaces,
|
||||
NotificationCenter.closeChats,
|
||||
NotificationCenter.contactsDidLoad,
|
||||
// NotificationCenter.contactsDidLoad,
|
||||
NotificationCenter.chatInfoCantLoad,
|
||||
NotificationCenter.userInfoDidLoad,
|
||||
NotificationCenter.pinnedInfoDidLoad,
|
||||
|
@ -700,7 +708,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
private int fixedKeyboardHeight = -1;
|
||||
private boolean invalidateMessagesVisiblePart;
|
||||
private boolean scrollByTouch;
|
||||
private ChatActionCell infoTopView1;
|
||||
|
||||
public float getChatListViewPadding() {
|
||||
return chatListViewPaddingTop;
|
||||
|
@ -1290,6 +1297,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
getNotificationCenter().addObserver(this, NotificationCenter.videoLoadingStateChanged);
|
||||
getNotificationCenter().addObserver(this, NotificationCenter.scheduledMessagesUpdated);
|
||||
getNotificationCenter().addObserver(this, NotificationCenter.diceStickersDidLoad);
|
||||
getNotificationCenter().addObserver(this, NotificationCenter.dialogDeleted);
|
||||
|
||||
super.onFragmentCreate();
|
||||
|
||||
|
@ -1309,7 +1317,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
int loadIndex = lastLoadIndex++;
|
||||
waitingForLoad.add(loadIndex);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialog_id, messageObjects.size(), messageObjects, false, 0, last_message_id, 0, 0, 2, true, classGuid, loadIndex, pinnedMessageIds.get(0), 0, MODE_PINNED);
|
||||
} else {
|
||||
} else if (!forceHistoryEmpty) {
|
||||
loading = true;
|
||||
}
|
||||
if (isThreadChat()) {
|
||||
|
@ -1363,7 +1371,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
loadInfo = userInfo == null;
|
||||
}
|
||||
|
||||
if (chatMode != MODE_PINNED) {
|
||||
if (forceHistoryEmpty) {
|
||||
endReached[0] = endReached[1] = true;
|
||||
forwardEndReached[0] = forwardEndReached[1] = true;
|
||||
firstLoading = false;
|
||||
}
|
||||
if (chatMode != MODE_PINNED && !forceHistoryEmpty) {
|
||||
waitingForLoad.add(lastLoadIndex);
|
||||
if (startLoadFromMessageId != 0 && (!isThreadChat() || startLoadFromMessageId == highlightMessageId)) {
|
||||
startLoadFromMessageIdSaved = startLoadFromMessageId;
|
||||
|
@ -1569,6 +1582,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
getNotificationCenter().removeObserver(this, NotificationCenter.videoLoadingStateChanged);
|
||||
getNotificationCenter().removeObserver(this, NotificationCenter.scheduledMessagesUpdated);
|
||||
getNotificationCenter().removeObserver(this, NotificationCenter.diceStickersDidLoad);
|
||||
getNotificationCenter().removeObserver(this, NotificationCenter.dialogDeleted);
|
||||
if (currentEncryptedChat != null) {
|
||||
getNotificationCenter().removeObserver(this, NotificationCenter.didVerifyMessagesStickers);
|
||||
}
|
||||
|
@ -1636,6 +1650,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
mediaBanTooltip = null;
|
||||
noSoundHintView = null;
|
||||
forwardHintView = null;
|
||||
checksHintView = null;
|
||||
textSelectionHint = null;
|
||||
emojiButtonRed = null;
|
||||
gifHintTextView = null;
|
||||
|
@ -1756,7 +1771,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
final boolean isChat = (int) dialog_id < 0 && (int) (dialog_id >> 32) != 1;
|
||||
|
||||
AlertsCreator.createClearOrDeleteDialogAlert(ChatActivity.this, id == clear_history, currentChat, currentUser, currentEncryptedChat != null, (param) -> {
|
||||
AlertsCreator.createClearOrDeleteDialogAlert(ChatActivity.this, id == clear_history, currentChat, currentUser, currentEncryptedChat != null, true, (param) -> {
|
||||
if (id == clear_history && ChatObject.isChannel(currentChat) && (!currentChat.megagroup || !TextUtils.isEmpty(currentChat.username))) {
|
||||
getMessagesController().deleteDialog(dialog_id, 2, param);
|
||||
} else {
|
||||
|
@ -2065,6 +2080,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
|
||||
editTextItem = menu.addItem(0, R.drawable.ic_ab_other);
|
||||
editTextItem.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions));
|
||||
editTextItem.setTag(null);
|
||||
editTextItem.setVisibility(View.GONE);
|
||||
|
||||
|
@ -2142,6 +2158,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
if (chatMode == 0 && !isThreadChat()) {
|
||||
attachItem = menu.addItem(chat_menu_attach, R.drawable.ic_ab_other).setOverrideMenuClick(true).setAllowCloseAnimation(false);
|
||||
attachItem.setContentDescription(LocaleController.getString("AccDescrAttachButton", R.string.AccDescrAttachButton));
|
||||
attachItem.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
@ -2236,6 +2253,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
chatListView.setItemAnimator(null);
|
||||
chatListView.invalidate();
|
||||
updateBulletinLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2338,7 +2356,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
if (scrimView != null && (child == pagedownButton || child == mentiondownButton || child == floatingDateView || child == fireworksOverlay)) {
|
||||
return false;
|
||||
}
|
||||
if (child == fragmentContextView && fragmentContextView.getCurrentStyle() == 3) {
|
||||
if (child == fragmentContextView && fragmentContextView.isCallStyle()) {
|
||||
return true;
|
||||
}
|
||||
if (getTag(BlurBehindDrawable.TAG_DRAWING_AS_BACKGROUND) != null ) {
|
||||
|
@ -2440,7 +2458,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
updateMessagesVisiblePart(false);
|
||||
}
|
||||
super.dispatchDraw(canvas);
|
||||
if (fragmentContextView != null && fragmentContextView.getCurrentStyle() == 3) {
|
||||
if (fragmentContextView != null && fragmentContextView.isCallStyle()) {
|
||||
canvas.save();
|
||||
canvas.translate(fragmentContextView.getX(), fragmentContextView.getY());
|
||||
fragmentContextView.setDrawOverlay(true);
|
||||
|
@ -2764,6 +2782,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
AndroidUtilities.runOnUIThread(() -> chatLayoutManager.scrollToPositionWithOffset(scrollTo, scrollToOffsetOnRecreate));
|
||||
scrollToPositionOnRecreate = -1;
|
||||
}
|
||||
|
||||
updateBulletinLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2843,7 +2863,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
if (child == blurredView) {
|
||||
childTop = 0;
|
||||
} else if (child instanceof HintView) {
|
||||
} else if (child instanceof HintView || child instanceof ChecksHintView) {
|
||||
childTop = 0;
|
||||
} else if (child == mentionContainer) {
|
||||
childTop -= chatActivityEnterView.getMeasuredHeight() - AndroidUtilities.dp(2);
|
||||
|
@ -2942,7 +2962,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
emptyViewContainer.setOnTouchListener((v, event) -> true);
|
||||
|
||||
int distance = getArguments().getInt("nearby_distance", -1);
|
||||
if (distance >= 0 && currentUser != null) {
|
||||
if ((distance >= 0 || preloadedGreetingsSticker != null) && currentUser != null) {
|
||||
greetingsViewContainer = new ChatGreetingsView(context, currentUser, distance, preloadedGreetingsSticker);
|
||||
greetingsViewContainer.setListener((sticker) -> {
|
||||
animatingDocuments.put(sticker, 0);
|
||||
|
@ -3040,7 +3060,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
public void setTranslationY(float translationY) {
|
||||
super.setTranslationY(translationY);
|
||||
if (emptyViewContainer != null) {
|
||||
emptyViewContainer.setTranslationY(translationY / 1.7f);
|
||||
if (chatActivityEnterView != null && chatActivityEnterView.pannelAniamationInProgress()) {
|
||||
emptyViewContainer.setTranslationY(translationY / 2f);
|
||||
} else {
|
||||
emptyViewContainer.setTranslationY(translationY / 1.7f);
|
||||
}
|
||||
}
|
||||
invalidateChatListViewTopPadding();
|
||||
invalidateMessagesVisiblePart();
|
||||
|
@ -3263,7 +3287,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e) {
|
||||
textSelectionHelper.checkSelectionCancel(e);
|
||||
if (e != null && e.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
if (e.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
scrollByTouch = true;
|
||||
}
|
||||
if (isFastScrollAnimationRunning()) {
|
||||
|
@ -4570,10 +4594,19 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
canvas.save();
|
||||
canvas.clipRect(0, 0, getMeasuredWidth(), AndroidUtilities.dp(48));
|
||||
}
|
||||
boolean result = super.drawChild(canvas, child, drawingTime);
|
||||
if (child == pinnedLineView) {
|
||||
boolean result;
|
||||
if (child == pinnedMessageTextView[0] || child == pinnedMessageTextView[1]) {
|
||||
canvas.save();
|
||||
canvas.clipRect(0,0,getMeasuredWidth() - AndroidUtilities.dp(38),getMeasuredHeight());
|
||||
result = super.drawChild(canvas, child, drawingTime);
|
||||
canvas.restore();
|
||||
} else {
|
||||
result = super.drawChild(canvas, child, drawingTime);
|
||||
if (child == pinnedLineView) {
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
@ -4778,6 +4811,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
if (ignoreLayout) {
|
||||
|
@ -4805,7 +4839,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
reportSpamButton.setSingleLine(true);
|
||||
reportSpamButton.setMaxLines(1);
|
||||
reportSpamButton.setGravity(Gravity.CENTER);
|
||||
topChatPanelView.addView(reportSpamButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, AndroidUtilities.dp(1)));
|
||||
topChatPanelView.addView(reportSpamButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 1));
|
||||
reportSpamButton.setOnClickListener(v2 -> AlertsCreator.showBlockReportSpamAlert(ChatActivity.this, dialog_id, currentUser, currentChat, currentEncryptedChat, reportSpamButton.getTag(R.id.object_tag) != null, chatInfo, param -> {
|
||||
if (param == 0) {
|
||||
updateTopPanel(true);
|
||||
|
@ -4824,9 +4858,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
addToContactsButton.setPadding(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), 0);
|
||||
addToContactsButton.setGravity(Gravity.CENTER);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
addToContactsButton.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_chat_addContact) & 0x19ffffff, 5));
|
||||
addToContactsButton.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_chat_addContact) & 0x19ffffff, 2));
|
||||
}
|
||||
topChatPanelView.addView(addToContactsButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, AndroidUtilities.dp(1)));
|
||||
topChatPanelView.addView(addToContactsButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 1));
|
||||
addToContactsButton.setOnClickListener(v -> {
|
||||
if (addToContactsButtonArchive) {
|
||||
getMessagesController().addDialogToFolder(dialog_id, 0, 0, 0);
|
||||
|
@ -4839,6 +4873,25 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
editor.commit();
|
||||
updateTopPanel(false);
|
||||
getNotificationsController().clearDialogNotificationsSettings(dialog_id);
|
||||
} else if (addToContactsButton.getTag() != null && (Integer) addToContactsButton.getTag() == 4) {
|
||||
if (chatInfo != null && chatInfo.participants != null) {
|
||||
SparseArray<TLObject> users = new SparseArray<>();
|
||||
for (int a = 0; a < chatInfo.participants.participants.size(); a++) {
|
||||
users.put(chatInfo.participants.participants.get(a).user_id, null);
|
||||
}
|
||||
int chatId = chatInfo.id;
|
||||
InviteMembersBottomSheet bottomSheet = new InviteMembersBottomSheet(context, currentAccount, users, chatInfo.id, ChatActivity.this);
|
||||
bottomSheet.setDelegate((users1, fwdCount) -> {
|
||||
for (int a = 0, N = users1.size(); a < N; a++) {
|
||||
TLRPC.User user = users1.get(a);
|
||||
getMessagesController().addUserToChat(chatId, user, fwdCount, null, ChatActivity.this, null);
|
||||
}
|
||||
getMessagesController().hidePeerSettingsBar(dialog_id, currentUser, currentChat);
|
||||
updateTopPanel(true);
|
||||
updateInfoTopView(true);
|
||||
});
|
||||
bottomSheet.show();
|
||||
}
|
||||
} else if (addToContactsButton.getTag() != null) {
|
||||
shareMyContact(1, null);
|
||||
} else {
|
||||
|
@ -4867,6 +4920,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
getMessagesController().hidePeerSettingsBar(did, currentUser, currentChat);
|
||||
updateTopPanel(true);
|
||||
updateInfoTopView(true);
|
||||
});
|
||||
|
||||
alertView = new FrameLayout(context);
|
||||
|
@ -4895,7 +4949,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
pagedownButton = new FrameLayout(context);
|
||||
pagedownButton.setVisibility(View.INVISIBLE);
|
||||
contentView.addView(pagedownButton, LayoutHelper.createFrame(66, 59, Gravity.RIGHT | Gravity.BOTTOM, 0, 0, -3, 5));
|
||||
contentView.addView(pagedownButton, LayoutHelper.createFrame(66, 61, Gravity.RIGHT | Gravity.BOTTOM, 0, 0, -3, 5));
|
||||
pagedownButton.setOnClickListener(view -> {
|
||||
wasManualScroll = true;
|
||||
textSelectionHelper.cancelTextSelectionRunnable();
|
||||
|
@ -4914,7 +4968,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
mentiondownButton = new FrameLayout(context);
|
||||
mentiondownButton.setVisibility(View.INVISIBLE);
|
||||
contentView.addView(mentiondownButton, LayoutHelper.createFrame(46, 59, Gravity.RIGHT | Gravity.BOTTOM, 0, 0, 7, 5));
|
||||
contentView.addView(mentiondownButton, LayoutHelper.createFrame(46, 61, Gravity.RIGHT | Gravity.BOTTOM, 0, 0, 7, 5));
|
||||
mentiondownButton.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
private void loadLastUnreadMention() {
|
||||
|
@ -5524,16 +5578,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
pagedownButton.addView(pagedownButtonImage, LayoutHelper.createFrame(46, 46, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM));
|
||||
pagedownButton.setContentDescription(LocaleController.getString("AccDescrPageDown", R.string.AccDescrPageDown));
|
||||
|
||||
pagedownButtonCounter = new SimpleTextView(context);
|
||||
pagedownButtonCounter.setVisibility(View.INVISIBLE);
|
||||
pagedownButtonCounter.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
pagedownButtonCounter.setTextSize(13);
|
||||
pagedownButtonCounter.setTextColor(Theme.getColor(Theme.key_chat_goDownButtonCounter));
|
||||
pagedownButtonCounter.setGravity(Gravity.CENTER);
|
||||
pagedownButtonCounter.setBackgroundDrawable(Theme.createRoundRectDrawable(AndroidUtilities.dp(11.5f), Theme.getColor(Theme.key_chat_goDownButtonCounterBackground)));
|
||||
pagedownButtonCounter.setMinWidth(AndroidUtilities.dp(23));
|
||||
pagedownButtonCounter.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(1), AndroidUtilities.dp(8), 0);
|
||||
pagedownButton.addView(pagedownButtonCounter, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 23, Gravity.TOP | Gravity.LEFT));
|
||||
pagedownButtonCounter = new CounterView(context);
|
||||
pagedownButtonCounter.setReverse(true);
|
||||
pagedownButton.addView(pagedownButtonCounter, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 28, Gravity.TOP | Gravity.LEFT));
|
||||
|
||||
mentiondownButtonImage = new ImageView(context);
|
||||
mentiondownButtonImage.setImageResource(R.drawable.mentionbutton);
|
||||
|
@ -5573,7 +5620,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
mentiondownButton.setContentDescription(LocaleController.getString("AccDescrMentionDown", R.string.AccDescrMentionDown));
|
||||
|
||||
contentView.addView(fragmentLocationContextView = new FragmentContextView(context, this, true), LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
|
||||
contentView.addView(fragmentContextView = new FragmentContextView(context, this, false), LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
|
||||
contentView.addView(fragmentContextView = new FragmentContextView(context, this, false) {
|
||||
@Override
|
||||
protected void playbackSpeedChanged(boolean enabled) {
|
||||
undoView.showWithAction(0, enabled ? UndoView.ACTION_PLAYBACK_SPEED_ENABLED : UndoView.ACTION_PLAYBACK_SPEED_DISABLED, null);
|
||||
}
|
||||
}, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
|
||||
fragmentContextView.setAdditionalContextView(fragmentLocationContextView);
|
||||
fragmentLocationContextView.setAdditionalContextView(fragmentContextView);
|
||||
|
||||
|
@ -6114,14 +6166,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
if (pagedownButton != null) {
|
||||
pagedownButton.setTranslationY(translation);
|
||||
}
|
||||
if (mentiondownButton != null) {
|
||||
mentiondownButton.setTranslationY(pagedownButton.getVisibility() != View.VISIBLE ? translation : translation - AndroidUtilities.dp(72));
|
||||
if (mentiondownButton != null) {
|
||||
mentiondownButton.setTranslationY(pagedownButton.getVisibility() != View.VISIBLE ? translation : translation - AndroidUtilities.dp(72));
|
||||
}
|
||||
}
|
||||
invalidateChatListViewTopPadding();
|
||||
invalidateMessagesVisiblePart();
|
||||
updateTextureViewPosition(false);
|
||||
contentView.invalidate();
|
||||
updateBulletinLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6237,7 +6290,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
DialogsActivity fragment = new DialogsActivity(args);
|
||||
fragment.setDelegate(ChatActivity.this);
|
||||
presentFragment(fragment);
|
||||
} else if (replyingMessageObject != null) {
|
||||
} else if (replyingMessageObject != null && (!isThreadChat() || replyingMessageObject.getId() != threadMessageId)) {
|
||||
scrollToMessageId(replyingMessageObject.getId(), 0, true, 0, true, 0);
|
||||
} else if (editingMessageObject != null) {
|
||||
if (editingMessageObject.canEditMedia() && editingMessageObjectReqId == 0) {
|
||||
|
@ -6645,7 +6698,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
toggleMute(true);
|
||||
}
|
||||
} else {
|
||||
AlertsCreator.createClearOrDeleteDialogAlert(ChatActivity.this, false, currentChat, currentUser, currentEncryptedChat != null, (param) -> {
|
||||
AlertsCreator.createClearOrDeleteDialogAlert(ChatActivity.this, false, currentChat, currentUser, currentEncryptedChat != null, true, (param) -> {
|
||||
getNotificationCenter().removeObserver(ChatActivity.this, NotificationCenter.closeChats);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.closeChats);
|
||||
finishFragment();
|
||||
|
@ -6809,6 +6862,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
return fragmentView;
|
||||
}
|
||||
|
||||
private void updateBulletinLayout() {
|
||||
Bulletin bulletin = Bulletin.getVisibleBulletin();
|
||||
if (bulletin != null && bulletinDelegate != null) {
|
||||
bulletin.updatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void searchUserMessages(TLRPC.User user, TLRPC.Chat chat) {
|
||||
searchingUserMessages = user;
|
||||
searchingChatMessages = chat;
|
||||
|
@ -8153,6 +8213,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
if (pollHintView != null) {
|
||||
pollHintView.hide();
|
||||
}
|
||||
if (checksHintView != null) {
|
||||
checksHintView.hide();
|
||||
}
|
||||
}
|
||||
|
||||
private void showSlowModeHint(View view, boolean show, CharSequence time) {
|
||||
|
@ -8296,6 +8359,47 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
}
|
||||
|
||||
private void checkChecksHint() {
|
||||
if (getMessagesController().pendingSuggestions.contains("NEWCOMER_TICKS")) {
|
||||
AndroidUtilities.runOnUIThread(this::showChecksHint, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void showChecksHint() {
|
||||
if (scrollingChatListView || chatListView == null || getParentActivity() == null || fragmentView == null || checksHintView != null && checksHintView.getTag() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (checksHintView == null) {
|
||||
SizeNotifierFrameLayout frameLayout = (SizeNotifierFrameLayout) fragmentView;
|
||||
int index = frameLayout.indexOfChild(chatActivityEnterView);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
checksHintView = new ChecksHintView(getParentActivity());
|
||||
frameLayout.addView(checksHintView, index + 1, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 10, 0, 10, 0));
|
||||
checksHintView.setAlpha(0.0f);
|
||||
checksHintView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
int count = chatListView.getChildCount();
|
||||
for (int a = 0; a < count; a++) {
|
||||
View child = chatListView.getChildAt(a);
|
||||
if (!(child instanceof ChatMessageCell)) {
|
||||
continue;
|
||||
}
|
||||
ChatMessageCell messageCell = (ChatMessageCell) child;
|
||||
MessageObject messageObject = messageCell.getMessageObject();
|
||||
if (messageObject == null || !messageObject.isOutOwner() || !messageObject.isSent()) {
|
||||
continue;
|
||||
}
|
||||
if (checksHintView.showForMessageCell(messageCell, true)) {
|
||||
getMessagesController().removeSuggestion("NEWCOMER_TICKS");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showForwardHint(ChatMessageCell cell) {
|
||||
if (scrollingChatListView || chatListView == null || getParentActivity() == null || fragmentView == null) {
|
||||
return;
|
||||
|
@ -8936,7 +9040,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
|
||||
private void searchLinks(final CharSequence charSequence, final boolean force) {
|
||||
if (currentEncryptedChat != null && (getMessagesController().secretWebpagePreview == 0 || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 46)) {
|
||||
if (currentEncryptedChat != null && (getMessagesController().secretWebpagePreview == 0 || AndroidUtilities.getPeerLayerVersion(currentEncryptedChat.layer) < 46) || editingMessageObject != null && !editingMessageObject.isWebpage()) {
|
||||
return;
|
||||
}
|
||||
if (force && foundWebPage != null) {
|
||||
|
@ -9105,6 +9209,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
}
|
||||
|
||||
public boolean shouldShowImport() {
|
||||
return openImport;
|
||||
}
|
||||
|
||||
public void setOpenImport() {
|
||||
openImport = true;
|
||||
}
|
||||
|
||||
private void checkBotKeyboard() {
|
||||
if (chatActivityEnterView == null || botButtons == null || userBlocked) {
|
||||
return;
|
||||
|
@ -10091,7 +10203,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
floatingDateView.setTranslationY(chatListView.getTranslationY() + chatListViewPaddingTop + floatingDateViewOffset - AndroidUtilities.dp(4));
|
||||
}
|
||||
invalidateChatListViewTopPadding();
|
||||
if (!firstLoading && !paused && !inPreviewMode && (fragmentOpened || inBubbleMode) && chatMode == 0 && !getMessagesController().ignoreSetOnline) {
|
||||
if (!firstLoading && !paused && !inPreviewMode && chatMode == 0 && !getMessagesController().ignoreSetOnline) {
|
||||
int scheduledRead = 0;
|
||||
if ((maxPositiveUnreadId != Integer.MIN_VALUE || maxNegativeUnreadId != Integer.MAX_VALUE)) {
|
||||
int counterDecrement = 0;
|
||||
|
@ -10155,26 +10267,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
private void inlineUpdate1() {
|
||||
if (prevSetUnreadCount != newUnreadMessageCount) {
|
||||
prevSetUnreadCount = newUnreadMessageCount;
|
||||
pagedownButtonCounter.setText(String.format("%d", newUnreadMessageCount));
|
||||
}
|
||||
if (newUnreadMessageCount <= 0) {
|
||||
if (pagedownButtonCounter.getVisibility() != View.INVISIBLE) {
|
||||
pagedownButtonCounter.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
} else {
|
||||
if (pagedownButtonCounter.getVisibility() != View.VISIBLE) {
|
||||
pagedownButtonCounter.setVisibility(View.VISIBLE);
|
||||
}
|
||||
pagedownButtonCounter.setCount(newUnreadMessageCount, openAnimationEnded);
|
||||
}
|
||||
}
|
||||
|
||||
private void inlineUpdate2() {
|
||||
if (prevSetUnreadCount != newUnreadMessageCount) {
|
||||
prevSetUnreadCount = newUnreadMessageCount;
|
||||
pagedownButtonCounter.setText(String.format("%d", newUnreadMessageCount));
|
||||
}
|
||||
if (pagedownButtonCounter.getVisibility() != View.INVISIBLE) {
|
||||
pagedownButtonCounter.setVisibility(View.INVISIBLE);
|
||||
pagedownButtonCounter.setCount(newUnreadMessageCount, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11239,7 +11339,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
} else if (chatMode == MODE_PINNED) {
|
||||
avatarContainer.setTitle(LocaleController.formatPluralString("PinnedMessagesCount", getPinnedMessagesCount()));
|
||||
} else if (currentChat != null) {
|
||||
avatarContainer.setTitle(currentChat.title, currentChat.scam);
|
||||
avatarContainer.setTitle(currentChat.title, currentChat.scam, currentChat.fake);
|
||||
} else if (currentUser != null) {
|
||||
if (currentUser.self) {
|
||||
avatarContainer.setTitle(LocaleController.getString("SavedMessages", R.string.SavedMessages));
|
||||
|
@ -11247,10 +11347,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
if (!TextUtils.isEmpty(currentUser.phone)) {
|
||||
avatarContainer.setTitle(PhoneFormat.getInstance().format("+" + currentUser.phone));
|
||||
} else {
|
||||
avatarContainer.setTitle(UserObject.getUserName(currentUser), currentUser.scam);
|
||||
avatarContainer.setTitle(UserObject.getUserName(currentUser), currentUser.scam, currentUser.fake);
|
||||
}
|
||||
} else {
|
||||
avatarContainer.setTitle(UserObject.getUserName(currentUser), currentUser.scam);
|
||||
avatarContainer.setTitle(UserObject.getUserName(currentUser), currentUser.scam, currentUser.fake);
|
||||
}
|
||||
}
|
||||
setParentActivityTitle(avatarContainer.getTitleTextView().getText());
|
||||
|
@ -12362,9 +12462,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
updatePagedownButtonVisibility(true);
|
||||
if (unread_to_load != 0) {
|
||||
if (pagedownButtonCounter != null) {
|
||||
pagedownButtonCounter.setVisibility(View.VISIBLE);
|
||||
if (prevSetUnreadCount != newUnreadMessageCount) {
|
||||
pagedownButtonCounter.setText(String.format("%d", newUnreadMessageCount = unread_to_load));
|
||||
pagedownButtonCounter.setCount(newUnreadMessageCount = unread_to_load, openAnimationEnded);
|
||||
prevSetUnreadCount = newUnreadMessageCount;
|
||||
}
|
||||
}
|
||||
|
@ -12439,7 +12538,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
if (first) {
|
||||
if (chatListView != null) {
|
||||
chatListView.setEmptyView(emptyViewContainer);
|
||||
if (!fragmentBeginToShow) {
|
||||
chatListView.setAnimateEmptyView(false, 1);
|
||||
chatListView.setEmptyView(emptyViewContainer);
|
||||
chatListView.setAnimateEmptyView(true, 1);
|
||||
} else {
|
||||
chatListView.setEmptyView(emptyViewContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -12818,16 +12923,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
if (pagedownButtonCounter != null) {
|
||||
if (prevSetUnreadCount != newUnreadMessageCount) {
|
||||
prevSetUnreadCount = newUnreadMessageCount;
|
||||
pagedownButtonCounter.setText(String.format("%d", newUnreadMessageCount));
|
||||
}
|
||||
if (newUnreadMessageCount <= 0) {
|
||||
if (pagedownButtonCounter.getVisibility() != View.INVISIBLE) {
|
||||
pagedownButtonCounter.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
} else {
|
||||
if (pagedownButtonCounter.getVisibility() != View.VISIBLE) {
|
||||
pagedownButtonCounter.setVisibility(View.VISIBLE);
|
||||
}
|
||||
pagedownButtonCounter.setCount(newUnreadMessageCount, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12950,6 +13046,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
}
|
||||
if (obj != null) {
|
||||
checkChecksHint();
|
||||
if (obj.shouldRemoveVideoEditedInfo) {
|
||||
obj.videoEditedInfo = null;
|
||||
obj.shouldRemoveVideoEditedInfo = false;
|
||||
|
@ -13462,7 +13559,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
MessageObject playing = cell.getMessageObject();
|
||||
if (playing != null && playing.getId() == mid) {
|
||||
MessageObject player = MediaController.getInstance().getPlayingMessageObject();
|
||||
if (player != null) {
|
||||
if (player != null && !cell.getSeekBar().isDragging()) {
|
||||
playing.audioProgress = player.audioProgress;
|
||||
playing.audioProgressSec = player.audioProgressSec;
|
||||
playing.audioPlayerDuration = player.audioPlayerDuration;
|
||||
|
@ -14210,6 +14307,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
cell.setCurrentDiceValue(true);
|
||||
}
|
||||
}
|
||||
} else if (id == NotificationCenter.dialogDeleted) {
|
||||
long did = (Long) args[0];
|
||||
if (did == dialog_id) {
|
||||
if (parentLayout != null && parentLayout.fragmentsStack.get(parentLayout.fragmentsStack.size() - 1) == this) {
|
||||
finishFragment();
|
||||
} else {
|
||||
removeSelfFromStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14611,7 +14717,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
pagedownButtonCounter.setVisibility(View.VISIBLE);
|
||||
if (prevSetUnreadCount != newUnreadMessageCount) {
|
||||
prevSetUnreadCount = newUnreadMessageCount;
|
||||
pagedownButtonCounter.setText(String.format("%d", newUnreadMessageCount));
|
||||
pagedownButtonCounter.setCount(newUnreadMessageCount, true);
|
||||
}
|
||||
}
|
||||
if (newMentionsCount != 0 && mentiondownButtonCounter != null) {
|
||||
|
@ -14937,10 +15043,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
}
|
||||
} else {
|
||||
if (newUnreadMessageCount != 0 && pagedownButtonCounter != null) {
|
||||
pagedownButtonCounter.setVisibility(View.VISIBLE);
|
||||
if (prevSetUnreadCount != newUnreadMessageCount) {
|
||||
prevSetUnreadCount = newUnreadMessageCount;
|
||||
pagedownButtonCounter.setText(String.format("%d", newUnreadMessageCount));
|
||||
pagedownButtonCounter.setCount(newUnreadMessageCount, true);
|
||||
}
|
||||
}
|
||||
canShowPagedownButton = true;
|
||||
|
@ -15220,9 +15325,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
createUnreadMessageAfterId = 0;
|
||||
removeMessageObject(unreadMessageObject);
|
||||
unreadMessageObject = null;
|
||||
if (pagedownButtonCounter != null) {
|
||||
pagedownButtonCounter.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
if (updateScheduled) {
|
||||
updateScheduledInterface(true);
|
||||
|
@ -16701,6 +16803,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
boolean showAdd = preferences.getBoolean("dialog_bar_add" + did, false);
|
||||
boolean showArchive = preferences.getBoolean("dialog_bar_archived" + dialog_id, false);
|
||||
boolean showGeo = preferences.getBoolean("dialog_bar_location" + did, false);
|
||||
boolean showAddMembersToGroup = preferences.getBoolean("dialog_bar_invite" + did, false);
|
||||
|
||||
if (showAddMembersToGroup) {
|
||||
show = true;
|
||||
}
|
||||
|
||||
if (showReport || showBlock || showGeo) {
|
||||
reportSpamButton.setVisibility(View.VISIBLE);
|
||||
|
@ -16710,7 +16817,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
addToContactsButtonArchive = false;
|
||||
TLRPC.User user = currentUser != null ? getMessagesController().getUser(currentUser.id) : null;
|
||||
if (user != null) {
|
||||
if (showAddMembersToGroup) {
|
||||
String str = LocaleController.getString("GroupAddMembers", R.string.GroupAddMembers);
|
||||
if (str != null) {
|
||||
str = str.toUpperCase();
|
||||
}
|
||||
addToContactsButton.setVisibility(View.VISIBLE);
|
||||
addToContactsButton.setText(str);
|
||||
addToContactsButton.setTag(4);
|
||||
addToContactsButton.setTextColor(Theme.getColor(Theme.key_chat_addContact));
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
Theme.setSelectorDrawableColor(addToContactsButton.getBackground(), Theme.getColor(Theme.key_chat_addContact) & 0x19ffffff, true);
|
||||
}
|
||||
reportSpamButton.setTag(Theme.key_chat_addContact);
|
||||
} else if (user != null) {
|
||||
if (UserObject.isReplyUser(user)) {
|
||||
addToContactsButton.setVisibility(View.GONE);
|
||||
} else if (!user.contact && !user.self && showAdd) {
|
||||
|
@ -16974,6 +17094,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
updateSecretStatus();
|
||||
}
|
||||
|
||||
Bulletin.Delegate bulletinDelegate;
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -16982,6 +17104,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
blurredView.setBackground(null);
|
||||
}
|
||||
activityResumeTime = System.currentTimeMillis();
|
||||
if (openImport && getSendMessagesHelper().getImportingHistory(dialog_id) != null) {
|
||||
ImportingAlert alert = new ImportingAlert(getParentActivity(), this);
|
||||
alert.setOnHideListener(dialog -> {
|
||||
if (fragmentContextView != null) {
|
||||
fragmentContextView.checkImport(false);
|
||||
}
|
||||
});
|
||||
showDialog(alert);
|
||||
openImport = false;
|
||||
}
|
||||
|
||||
AndroidUtilities.requestAdjustResize(getParentActivity(), classGuid);
|
||||
MediaController.getInstance().startRaiseToEarSensors(this);
|
||||
|
@ -16992,20 +17124,26 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
if (contentView != null) {
|
||||
contentView.onResume();
|
||||
}
|
||||
checkChecksHint();
|
||||
|
||||
Bulletin.addDelegate(this, new Bulletin.Delegate() {
|
||||
Bulletin.addDelegate(this, bulletinDelegate = new Bulletin.Delegate() {
|
||||
@Override
|
||||
public int getBottomOffset() {
|
||||
final int height;
|
||||
int height;
|
||||
if (chatActivityEnterView != null && chatActivityEnterView.getVisibility() == View.VISIBLE) {
|
||||
final EmojiView emojiView = chatActivityEnterView.getEmojiView();
|
||||
if (emojiView != null && emojiView.getVisibility() == View.VISIBLE) {
|
||||
return 0;
|
||||
if (contentView.getKeyboardHeight() < AndroidUtilities.dp(20) && chatActivityEnterView.isPopupShowing() || chatActivityEnterView.pannelAniamationInProgress()) {
|
||||
height = chatActivityEnterView.getHeight() + chatActivityEnterView.getEmojiPadding();
|
||||
} else {
|
||||
height = chatActivityEnterView.getHeight();
|
||||
}
|
||||
height = chatActivityEnterView.getHeight();
|
||||
} else {
|
||||
height = AndroidUtilities.dp(51);
|
||||
}
|
||||
if (chatActivityEnterView.pannelAniamationInProgress()) {
|
||||
float translationY = bottomPanelTranslationY - chatActivityEnterView.getEmojiPadding();
|
||||
height += translationY;
|
||||
}
|
||||
height += contentPanTranslation;
|
||||
return height - AndroidUtilities.dp(1.5f);
|
||||
}
|
||||
});
|
||||
|
@ -18180,6 +18318,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
return;
|
||||
}
|
||||
processSelectedOption(options.get(i));
|
||||
scrimView = null;
|
||||
contentView.invalidate();
|
||||
chatListView.invalidate();
|
||||
if (scrimPopupWindow != null) {
|
||||
scrimPopupWindow.dismiss();
|
||||
}
|
||||
|
@ -18582,6 +18723,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
AndroidUtilities.addToClipboard(getMessageContent(selectedObject, 0, false));
|
||||
}
|
||||
}
|
||||
undoView.showWithAction(0, UndoView.ACTION_TEXT_COPIED, null);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
|
@ -19166,6 +19308,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
getSendMessagesHelper().sendMessage(fmessages, did, true, 0);
|
||||
}
|
||||
fragment.finishFragment();
|
||||
if (dids.size() == 1) {
|
||||
undoView.showWithAction(dids.get(0), UndoView.ACTION_FWD_MESSAGES, fmessages.size());
|
||||
} else {
|
||||
undoView.showWithAction(0, UndoView.ACTION_FWD_MESSAGES, fmessages.size(), dids.size(), null, null);
|
||||
}
|
||||
} else {
|
||||
long did = dids.get(0);
|
||||
if (did != dialog_id || chatMode == MODE_PINNED) {
|
||||
|
@ -20439,6 +20586,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
fragmentView.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSend(LongSparseArray<TLRPC.Dialog> dids, int count) {
|
||||
if (dids.size() == 1) {
|
||||
undoView.showWithAction(dids.valueAt(0).id, UndoView.ACTION_FWD_MESSAGES, count);
|
||||
} else {
|
||||
undoView.showWithAction(0, UndoView.ACTION_FWD_MESSAGES, count, dids.size(), null, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
AndroidUtilities.setAdjustResizeToNothing(getParentActivity(), classGuid);
|
||||
fragmentView.requestLayout();
|
||||
|
@ -20462,6 +20618,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
showNoSoundHint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didPressTime(ChatMessageCell cell) {
|
||||
undoView.showWithAction(dialog_id, UndoView.ACTION_IMPORT_INFO, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didPressChannelAvatar(ChatMessageCell cell, TLRPC.Chat chat, int postId, float touchX, float touchY) {
|
||||
if (chat == null) {
|
||||
|
@ -20476,6 +20637,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
|
||||
@Override
|
||||
public void didPressHiddenForward(ChatMessageCell cell) {
|
||||
if (cell.getMessageObject().isImportedForward()) {
|
||||
didPressTime(cell);
|
||||
return;
|
||||
}
|
||||
showForwardHint(cell);
|
||||
}
|
||||
|
||||
|
@ -21120,7 +21285,23 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
MessageObject nextMessage = messages.get(nextPosition - messagesStartRow);
|
||||
pinnedBottom = nextMessage.isOutOwner() == message.isOutOwner() && Math.abs(nextMessage.messageOwner.date - message.messageOwner.date) <= 5 * 60;
|
||||
if (pinnedBottom) {
|
||||
if (currentChat != null) {
|
||||
if (message.isImportedForward() || nextMessage.isImportedForward()) {
|
||||
if (message.isImportedForward() && nextMessage.isImportedForward()) {
|
||||
if (Math.abs(nextMessage.messageOwner.fwd_from.date - message.messageOwner.fwd_from.date) <= 5 * 60) {
|
||||
if (nextMessage.messageOwner.fwd_from.from_name != null && message.messageOwner.fwd_from.from_name != null) {
|
||||
pinnedBottom = nextMessage.messageOwner.fwd_from.from_name.equals(message.messageOwner.fwd_from.from_name);
|
||||
} else if (nextMessage.messageOwner.fwd_from.from_id != null && message.messageOwner.fwd_from.from_id != null) {
|
||||
pinnedBottom = MessageObject.getPeerId(nextMessage.messageOwner.fwd_from.from_id) == MessageObject.getPeerId(message.messageOwner.fwd_from.from_id);
|
||||
} else {
|
||||
pinnedBottom = false;
|
||||
}
|
||||
} else {
|
||||
pinnedBottom = false;
|
||||
}
|
||||
} else {
|
||||
pinnedBottom = false;
|
||||
}
|
||||
} else if (currentChat != null) {
|
||||
int fromId = nextMessage.getFromChatId();
|
||||
pinnedBottom = fromId == message.getFromChatId();
|
||||
if (!pinnedBottomByGroup && pinnedBottom && fromId < 0 && currentChat.megagroup) {
|
||||
|
@ -21139,9 +21320,25 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
MessageObject prevMessage = messages.get(prevPosition - messagesStartRow);
|
||||
pinnedTop = !prevMessage.hasReactions() && !(prevMessage.messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup) && prevMessage.isOutOwner() == message.isOutOwner() && Math.abs(prevMessage.messageOwner.date - message.messageOwner.date) <= 5 * 60;
|
||||
if (pinnedTop) {
|
||||
if (currentChat != null) {
|
||||
if (message.isImportedForward() || prevMessage.isImportedForward()) {
|
||||
if (message.isImportedForward() && prevMessage.isImportedForward()) {
|
||||
if (Math.abs(message.messageOwner.fwd_from.date - prevMessage.messageOwner.fwd_from.date) <= 5 * 60) {
|
||||
if (prevMessage.messageOwner.fwd_from.from_name != null && message.messageOwner.fwd_from.from_name != null) {
|
||||
pinnedTop = prevMessage.messageOwner.fwd_from.from_name.equals(message.messageOwner.fwd_from.from_name);
|
||||
} else if (prevMessage.messageOwner.fwd_from.from_id != null && message.messageOwner.fwd_from.from_id != null) {
|
||||
pinnedTop = MessageObject.getPeerId(prevMessage.messageOwner.fwd_from.from_id) == MessageObject.getPeerId(message.messageOwner.fwd_from.from_id);
|
||||
} else {
|
||||
pinnedTop = false;
|
||||
}
|
||||
} else {
|
||||
pinnedTop = false;
|
||||
}
|
||||
} else {
|
||||
pinnedTop = false;
|
||||
}
|
||||
} else if (currentChat != null) {
|
||||
int fromId = prevMessage.getFromChatId();
|
||||
pinnedTop = fromId == message.getFromChatId();
|
||||
pinnedTop = fromId == message.getFromChatId() && !message.isImportedForward() && !prevMessage.isImportedForward();
|
||||
if (!pinnedTopByGroup && pinnedTop && fromId < 0 && currentChat.megagroup) {
|
||||
pinnedTop = false;
|
||||
}
|
||||
|
@ -21718,8 +21915,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
return false;
|
||||
}
|
||||
|
||||
public void setPreloadedSticker(TLRPC.Document preloadedSticker) {
|
||||
public void setPreloadedSticker(TLRPC.Document preloadedSticker, boolean historyEmpty) {
|
||||
preloadedGreetingsSticker = preloadedSticker;
|
||||
forceHistoryEmpty = historyEmpty;
|
||||
}
|
||||
|
||||
public class ChatScrollCallback extends RecyclerAnimationScrollHelper.AnimationCallback {
|
||||
|
@ -22067,6 +22265,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_pollHintDrawable[1]}, null, Theme.key_chat_outPreviewInstantText));
|
||||
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_psaHelpDrawable[0]}, null, Theme.key_chat_inViews));
|
||||
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_psaHelpDrawable[1]}, null, Theme.key_chat_outViews));
|
||||
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, null, null, Theme.key_chat_shareBackground));
|
||||
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, null, null, Theme.key_chat_shareBackgroundSelected));
|
||||
|
||||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, null, Theme.avatarDrawables, null, Theme.key_avatar_text));
|
||||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, Theme.dialogs_countPaint, null, null, Theme.key_chats_unreadCounter));
|
||||
|
@ -22074,7 +22274,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, null, new Paint[]{Theme.dialogs_nameEncryptedPaint[0], Theme.dialogs_nameEncryptedPaint[1], Theme.dialogs_searchNameEncryptedPaint}, null, null, Theme.key_chats_secretName));
|
||||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, null, new Drawable[]{Theme.dialogs_lockDrawable}, null, Theme.key_chats_secretIcon));
|
||||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, null, new Drawable[]{Theme.dialogs_groupDrawable, Theme.dialogs_broadcastDrawable, Theme.dialogs_botDrawable}, null, Theme.key_chats_nameIcon));
|
||||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, null, new Drawable[]{Theme.dialogs_scamDrawable}, null, Theme.key_chats_draft));
|
||||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, null, new Drawable[]{Theme.dialogs_scamDrawable, Theme.dialogs_fakeDrawable}, null, Theme.key_chats_draft));
|
||||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, Theme.dialogs_messagePaint[1], null, null, Theme.key_chats_message_threeLines));
|
||||
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, Theme.dialogs_messageNamePaint, null, null, Theme.key_chats_nameMessage_threeLines));
|
||||
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, selectedBackgroundDelegate, Theme.key_chats_nameMessage));
|
||||
|
@ -22186,7 +22386,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND | ThemeDescription.FLAG_CHECKTAG, new Class[]{FragmentContextView.class}, new String[]{"frameLayout"}, null, null, null, Theme.key_inappPlayerBackground));
|
||||
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{FragmentContextView.class}, new String[]{"playButton"}, null, null, null, Theme.key_inappPlayerPlayPause));
|
||||
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_TEXTCOLOR | ThemeDescription.FLAG_CHECKTAG, new Class[]{FragmentContextView.class}, new String[]{"titleTextView"}, null, null, null, Theme.key_inappPlayerTitle));
|
||||
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_TEXTCOLOR | ThemeDescription.FLAG_FASTSCROLL, new Class[]{FragmentContextView.class}, new String[]{"titleTextView"}, null, null, null, Theme.key_inappPlayerPerformer));
|
||||
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_TEXTCOLOR | ThemeDescription.FLAG_CHECKTAG, new Class[]{FragmentContextView.class}, new String[]{"titleTextView"}, null, null, null, Theme.key_inappPlayerPerformer));
|
||||
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_TEXTCOLOR | ThemeDescription.FLAG_FASTSCROLL, new Class[]{FragmentContextView.class}, new String[]{"subtitleTextView"}, null, null, null, Theme.key_inappPlayerClose));
|
||||
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_IMAGECOLOR, new Class[]{FragmentContextView.class}, new String[]{"closeButton"}, null, null, null, Theme.key_inappPlayerClose));
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.telegram.messenger.MessagesController;
|
|||
import org.telegram.messenger.MessagesStorage;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.ActionBar;
|
||||
import org.telegram.ui.ActionBar.ActionBarMenu;
|
||||
|
@ -108,6 +107,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
|
||||
private LinearLayout infoContainer;
|
||||
private TextCell membersCell;
|
||||
private TextCell inviteLinksCell;
|
||||
private TextCell adminCell;
|
||||
private TextCell blockCell;
|
||||
private TextCell logCell;
|
||||
|
@ -209,9 +209,28 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
signMessages = currentChat.signatures;
|
||||
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.chatInfoDidLoad);
|
||||
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.updateInterfaces);
|
||||
|
||||
if (info != null) {
|
||||
loadLinksCount();
|
||||
}
|
||||
return super.onFragmentCreate();
|
||||
}
|
||||
|
||||
private void loadLinksCount() {
|
||||
// TLRPC.TL_messages_getExportedChatInvites req = new TLRPC.TL_messages_getExportedChatInvites();
|
||||
// req.peer = getMessagesController().getInputPeer(-chatId);
|
||||
// req.admin_id = getMessagesController().getInputUser(getUserConfig().getCurrentUser());
|
||||
// req.limit = 0;
|
||||
// getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
// if (error == null) {
|
||||
// TLRPC.TL_messages_exportedChatInvites invites = (TLRPC.TL_messages_exportedChatInvites) response;
|
||||
// info.invitesCount = invites.count;
|
||||
// getMessagesStorage().saveChatLinksCount(chatId, info.invitesCount);
|
||||
// updateFields(false);
|
||||
// }
|
||||
// }));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFragmentDestroy() {
|
||||
super.onFragmentDestroy();
|
||||
|
@ -555,7 +574,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
MessagesController.getInstance(currentAccount).changeChatAvatar(chatId, null, null, null, 0, null, null, null);
|
||||
showAvatarProgress(false, true);
|
||||
avatarImage.setImage(null, null, avatarDrawable, currentChat);
|
||||
}));
|
||||
}, null));
|
||||
settingsContainer.addView(setAvatarCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
}
|
||||
|
||||
|
@ -753,6 +772,14 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
presentFragment(fragment);
|
||||
});
|
||||
|
||||
// inviteLinksCell = new TextCell(context);
|
||||
// inviteLinksCell.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
// inviteLinksCell.setOnClickListener(v -> {
|
||||
// ManageLinksActivity fragment = new ManageLinksActivity(chatId);
|
||||
// fragment.setInfo(info, info.exported_invite);
|
||||
// presentFragment(fragment);
|
||||
// });
|
||||
|
||||
adminCell = new TextCell(context);
|
||||
adminCell.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
adminCell.setOnClickListener(v -> {
|
||||
|
@ -785,6 +812,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
if (!isChannel) {
|
||||
infoContainer.addView(blockCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
}
|
||||
// infoContainer.addView(inviteLinksCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
infoContainer.addView(adminCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
infoContainer.addView(membersCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
if (isChannel) {
|
||||
|
@ -832,20 +860,18 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
deleteCell.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
if (isChannel) {
|
||||
deleteCell.setText(LocaleController.getString("ChannelDelete", R.string.ChannelDelete), false);
|
||||
} else if (currentChat.megagroup) {
|
||||
deleteCell.setText(LocaleController.getString("DeleteMega", R.string.DeleteMega), false);
|
||||
} else {
|
||||
deleteCell.setText(LocaleController.getString("DeleteAndExitButton", R.string.DeleteAndExitButton), false);
|
||||
}
|
||||
deleteContainer.addView(deleteCell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
deleteCell.setOnClickListener(v -> AlertsCreator.createClearOrDeleteDialogAlert(ChatEditActivity.this, false, true, false, currentChat, null, false, (param) -> {
|
||||
deleteCell.setOnClickListener(v -> AlertsCreator.createClearOrDeleteDialogAlert(ChatEditActivity.this, false, true, false, currentChat, null, false, true, (param) -> {
|
||||
if (AndroidUtilities.isTablet()) {
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats, -(long) chatId);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.closeChats, -(long) chatId);
|
||||
} else {
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.closeChats);
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.closeChats);
|
||||
}
|
||||
MessagesController.getInstance(currentAccount).deleteUserFromChat(chatId, MessagesController.getInstance(currentAccount).getUser(UserConfig.getInstance(currentAccount).getClientUserId()), info, true, false);
|
||||
finishFragment();
|
||||
getNotificationCenter().postNotificationName(NotificationCenter.needDeleteDialog, (long) -currentChat.id, null, currentChat, param);
|
||||
}));
|
||||
|
||||
deleteInfoCell = new ShadowSectionCell(context);
|
||||
|
@ -917,9 +943,13 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
if (info == null && descriptionTextView != null) {
|
||||
descriptionTextView.setText(chatFull.about);
|
||||
}
|
||||
boolean infoWasEmpty = info == null;
|
||||
info = chatFull;
|
||||
historyHidden = !ChatObject.isChannel(currentChat) || info.hidden_prehistory;
|
||||
updateFields(false);
|
||||
if (infoWasEmpty) {
|
||||
loadLinksCount();
|
||||
}
|
||||
}
|
||||
} else if (id == NotificationCenter.updateInterfaces) {
|
||||
int mask = (Integer) args[0];
|
||||
|
@ -1324,6 +1354,11 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
}
|
||||
adminCell.setTextAndIcon(LocaleController.getString("ChannelAdministrators", R.string.ChannelAdministrators), R.drawable.actions_addadmin, true);
|
||||
}
|
||||
// if (info != null && info.invitesCount >= 0) {
|
||||
// inviteLinksCell.setTextAndValueAndIcon(LocaleController.getString("InviteLinks", R.string.InviteLinks), Integer.toString(info.invitesCount), R.drawable.actions_link, true);
|
||||
// } else {
|
||||
// inviteLinksCell.setTextAndIcon(LocaleController.getString("InviteLinks", R.string.InviteLinks), R.drawable.actions_link, true);
|
||||
// }
|
||||
}
|
||||
|
||||
if (stickersCell != null && info != null) {
|
||||
|
@ -1361,6 +1396,10 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
|
|||
themeDescriptions.add(new ThemeDescription(adminCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
themeDescriptions.add(new ThemeDescription(adminCell, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
themeDescriptions.add(new ThemeDescription(adminCell, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon));
|
||||
// themeDescriptions.add(new ThemeDescription(inviteLinksCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
// themeDescriptions.add(new ThemeDescription(inviteLinksCell, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
// themeDescriptions.add(new ThemeDescription(inviteLinksCell, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon));
|
||||
|
||||
themeDescriptions.add(new ThemeDescription(blockCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
themeDescriptions.add(new ThemeDescription(blockCell, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
themeDescriptions.add(new ThemeDescription(blockCell, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon));
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
package org.telegram.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Vibrator;
|
||||
import android.text.Editable;
|
||||
|
@ -24,9 +23,7 @@ import android.widget.LinearLayout;
|
|||
import android.widget.ScrollView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ApplicationLoader;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
|
@ -44,14 +41,16 @@ import org.telegram.ui.Cells.HeaderCell;
|
|||
import org.telegram.ui.Cells.LoadingCell;
|
||||
import org.telegram.ui.Cells.RadioButtonCell;
|
||||
import org.telegram.ui.Cells.ShadowSectionCell;
|
||||
import org.telegram.ui.Cells.TextBlockCell;
|
||||
import org.telegram.ui.Cells.TextCell;
|
||||
import org.telegram.ui.Cells.TextInfoPrivacyCell;
|
||||
import org.telegram.ui.Cells.TextSettingsCell;
|
||||
import org.telegram.ui.Components.BulletinFactory;
|
||||
import org.telegram.ui.Components.EditTextBoldCursor;
|
||||
import org.telegram.ui.Components.InviteLinkBottomSheet;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.LinkActionView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class ChatEditTypeActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
@ -72,10 +71,9 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
private LinearLayout linkContainer;
|
||||
private LinearLayout publicContainer;
|
||||
private LinearLayout privateContainer;
|
||||
private TextBlockCell privateTextView;
|
||||
private TextSettingsCell copyCell;
|
||||
private TextSettingsCell revokeCell;
|
||||
private TextSettingsCell shareCell;
|
||||
private LinkActionView permanentLinkView;
|
||||
// private TextCell manageLinksTextView;
|
||||
// private TextInfoPrivacyCell manageLinksInfoCell;
|
||||
private ShadowSectionCell sectionCell2;
|
||||
private TextInfoPrivacyCell infoCell;
|
||||
private TextSettingsCell textCell;
|
||||
|
@ -99,13 +97,15 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
private Runnable checkRunnable;
|
||||
private boolean lastNameAvailable;
|
||||
private boolean loadingInvite;
|
||||
private TLRPC.ExportedChatInvite invite;
|
||||
private TLRPC.TL_chatInviteExported invite;
|
||||
|
||||
private boolean ignoreTextChanges;
|
||||
|
||||
private boolean isForcePublic;
|
||||
HashMap<Integer, TLRPC.User> usersMap = new HashMap<>();
|
||||
|
||||
private final static int done_button = 1;
|
||||
private InviteLinkBottomSheet inviteLinkBottomSheet;
|
||||
|
||||
public ChatEditTypeActivity(int id, boolean forcePublic) {
|
||||
chatId = id;
|
||||
|
@ -142,6 +142,9 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
}
|
||||
}));
|
||||
}
|
||||
if (isPrivate && info != null) {
|
||||
getMessagesController().loadFullChat(chatId, classGuid, true);
|
||||
}
|
||||
getNotificationCenter().addObserver(this, NotificationCenter.chatInfoDidLoad);
|
||||
return super.onFragmentCreate();
|
||||
}
|
||||
|
@ -164,6 +167,11 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
textCell2.setText(LocaleController.getString("GroupStickers", R.string.GroupStickers), false);
|
||||
}
|
||||
}
|
||||
if (info != null) {
|
||||
invite = info.exported_invite;
|
||||
permanentLinkView.setLink(invite == null ? null : invite.link);
|
||||
permanentLinkView.loadUsers(invite, chatId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -340,71 +348,21 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
privateContainer.setOrientation(LinearLayout.VERTICAL);
|
||||
linkContainer.addView(privateContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
privateTextView = new TextBlockCell(context);
|
||||
privateTextView.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
privateContainer.addView(privateTextView);
|
||||
privateTextView.setOnClickListener(v -> {
|
||||
if (invite == null) {
|
||||
return;
|
||||
permanentLinkView = new LinkActionView(context, this, null, chatId, true);
|
||||
permanentLinkView.setDelegate(new LinkActionView.Delegate() {
|
||||
@Override
|
||||
public void revokeLink() {
|
||||
ChatEditTypeActivity.this.generateLink(true);
|
||||
}
|
||||
try {
|
||||
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
android.content.ClipData clip = android.content.ClipData.newPlainText("label", invite.link);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
BulletinFactory.createCopyLinkBulletin(this).show();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
|
||||
copyCell = new TextSettingsCell(context);
|
||||
copyCell.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
copyCell.setText(LocaleController.getString("CopyLink", R.string.CopyLink), true);
|
||||
privateContainer.addView(copyCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
copyCell.setOnClickListener(v -> {
|
||||
if (invite == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
android.content.ClipData clip = android.content.ClipData.newPlainText("label", invite.link);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
BulletinFactory.createCopyLinkBulletin(this).show();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
});
|
||||
|
||||
revokeCell = new TextSettingsCell(context);
|
||||
revokeCell.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
revokeCell.setText(LocaleController.getString("RevokeLink", R.string.RevokeLink), true);
|
||||
privateContainer.addView(revokeCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
revokeCell.setOnClickListener(v -> {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
|
||||
builder.setMessage(LocaleController.getString("RevokeAlert", R.string.RevokeAlert));
|
||||
builder.setTitle(LocaleController.getString("RevokeLink", R.string.RevokeLink));
|
||||
builder.setPositiveButton(LocaleController.getString("RevokeButton", R.string.RevokeButton), (dialogInterface, i) -> generateLink(true));
|
||||
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
|
||||
showDialog(builder.create());
|
||||
});
|
||||
|
||||
shareCell = new TextSettingsCell(context);
|
||||
shareCell.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
shareCell.setText(LocaleController.getString("ShareLink", R.string.ShareLink), false);
|
||||
privateContainer.addView(shareCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
shareCell.setOnClickListener(v -> {
|
||||
if (invite == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.setType("text/plain");
|
||||
intent.putExtra(Intent.EXTRA_TEXT, invite.link);
|
||||
getParentActivity().startActivityForResult(Intent.createChooser(intent, LocaleController.getString("InviteToGroupByLink", R.string.InviteToGroupByLink)), 500);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
@Override
|
||||
public void showUsersForPermanentLink() {
|
||||
inviteLinkBottomSheet = new InviteLinkBottomSheet(context, invite, info, usersMap, ChatEditTypeActivity.this, chatId, true);
|
||||
inviteLinkBottomSheet.show();
|
||||
}
|
||||
});
|
||||
permanentLinkView.setUsers(0, null);
|
||||
privateContainer.addView(permanentLinkView);
|
||||
|
||||
checkTextView = new TextInfoPrivacyCell(context);
|
||||
checkTextView.setBackgroundDrawable(Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
|
||||
|
@ -425,6 +383,25 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
adminedInfoCell = new ShadowSectionCell(context);
|
||||
linearLayout.addView(adminedInfoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
|
||||
// manageLinksTextView = new TextCell(context);
|
||||
// manageLinksTextView.setBackgroundDrawable(Theme.getSelectorDrawable(true));
|
||||
// manageLinksTextView.setOnClickListener(v -> {
|
||||
// if (invite == null) {
|
||||
// return;
|
||||
// }
|
||||
// });
|
||||
// manageLinksTextView.setTextAndIcon(LocaleController.getString("ManageInviteLinks", R.string.ManageInviteLinks), R.drawable.actions_link, false);
|
||||
// manageLinksTextView.setOnClickListener(v -> {
|
||||
// ManageLinksActivity fragment = new ManageLinksActivity(chatId);
|
||||
// fragment.setInfo(info, invite);
|
||||
// presentFragment(fragment);
|
||||
// });
|
||||
// linearLayout.addView(manageLinksTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
//
|
||||
// manageLinksInfoCell = new TextInfoPrivacyCell(context);
|
||||
// linearLayout.addView(manageLinksInfoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
if (!isPrivate && currentChat.username != null) {
|
||||
ignoreTextChanges = true;
|
||||
usernameTextView.setText(currentChat.username);
|
||||
|
@ -451,7 +428,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
public void setInfo(TLRPC.ChatFull chatFull) {
|
||||
info = chatFull;
|
||||
if (chatFull != null) {
|
||||
if (chatFull.exported_invite instanceof TLRPC.TL_chatInviteExported) {
|
||||
if (chatFull.exported_invite != null) {
|
||||
invite = chatFull.exported_invite;
|
||||
} else {
|
||||
generateLink(false);
|
||||
|
@ -603,10 +580,19 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
}
|
||||
publicContainer.setVisibility(isPrivate ? View.GONE : View.VISIBLE);
|
||||
privateContainer.setVisibility(isPrivate ? View.VISIBLE : View.GONE);
|
||||
//manageLinksTextView.setVisibility(isPrivate ? View.VISIBLE : View.GONE);
|
||||
// manageLinksInfoCell.setVisibility(isPrivate ? View.VISIBLE : View.GONE);
|
||||
linkContainer.setPadding(0, 0, 0, isPrivate ? 0 : AndroidUtilities.dp(7));
|
||||
privateTextView.setText(invite != null ? invite.link : LocaleController.getString("Loading", R.string.Loading), true);
|
||||
permanentLinkView.setLink(invite != null ? invite.link : null);
|
||||
permanentLinkView.loadUsers(invite, chatId);
|
||||
checkTextView.setVisibility(!isPrivate && checkTextView.length() != 0 ? View.VISIBLE : View.GONE);
|
||||
typeInfoCell.setBackgroundDrawable(checkTextView.getVisibility() == View.VISIBLE ? null : Theme.getThemedDrawable(typeInfoCell.getContext(), R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
|
||||
if (isPrivate) {
|
||||
typeInfoCell.setBackgroundDrawable(Theme.getThemedDrawable(typeInfoCell.getContext(), R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
|
||||
// manageLinksInfoCell.setBackground(Theme.getThemedDrawable(typeInfoCell.getContext(), R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
|
||||
// manageLinksInfoCell.setText(LocaleController.getString("ManageLinksInfoHelp", R.string.ManageLinksInfoHelp));
|
||||
} else {
|
||||
typeInfoCell.setBackgroundDrawable(checkTextView.getVisibility() == View.VISIBLE ? null : Theme.getThemedDrawable(typeInfoCell.getContext(), R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
|
||||
}
|
||||
}
|
||||
radioButtonCell1.setChecked(!isPrivate, true);
|
||||
radioButtonCell2.setChecked(isPrivate, true);
|
||||
|
@ -702,10 +688,11 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
private void generateLink(final boolean newRequest) {
|
||||
loadingInvite = true;
|
||||
TLRPC.TL_messages_exportChatInvite req = new TLRPC.TL_messages_exportChatInvite();
|
||||
//req.legacy_revoke_permanent = true; TODO layer 124
|
||||
req.peer = getMessagesController().getInputPeer(-chatId);
|
||||
final int reqId = getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
if (error == null) {
|
||||
invite = (TLRPC.ExportedChatInvite) response;
|
||||
invite = (TLRPC.TL_chatInviteExported) response;
|
||||
if (info != null) {
|
||||
info.exported_invite = invite;
|
||||
}
|
||||
|
@ -721,8 +708,9 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
}
|
||||
}
|
||||
loadingInvite = false;
|
||||
if (privateTextView != null) {
|
||||
privateTextView.setText(invite != null ? invite.link : LocaleController.getString("Loading", R.string.Loading), true);
|
||||
if (permanentLinkView != null) {
|
||||
permanentLinkView.setLink(invite != null ? invite.link : null);
|
||||
permanentLinkView.loadUsers(invite, chatId);
|
||||
}
|
||||
}));
|
||||
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
|
||||
|
@ -730,7 +718,8 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
|
||||
@Override
|
||||
public ArrayList<ThemeDescription> getThemeDescriptions() {
|
||||
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();ThemeDescription.ThemeDescriptionDelegate cellDelegate = () -> {
|
||||
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
|
||||
ThemeDescription.ThemeDescriptionDelegate cellDelegate = () -> {
|
||||
if (adminnedChannelsLayout != null) {
|
||||
int count = adminnedChannelsLayout.getChildCount();
|
||||
for (int a = 0; a < count; a++) {
|
||||
|
@ -740,6 +729,12 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
permanentLinkView.updateColors();
|
||||
// manageLinksTextView.setBackgroundDrawable(Theme.getSelectorDrawable(true));
|
||||
if (inviteLinkBottomSheet != null) {
|
||||
inviteLinkBottomSheet.updateColors();
|
||||
}
|
||||
};
|
||||
|
||||
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundGray));
|
||||
|
@ -777,10 +772,12 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
themeDescriptions.add(new ThemeDescription(typeInfoCell, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText4));
|
||||
themeDescriptions.add(new ThemeDescription(typeInfoCell, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText4));
|
||||
|
||||
// themeDescriptions.add(new ThemeDescription(manageLinksInfoCell, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow));
|
||||
// themeDescriptions.add(new ThemeDescription(manageLinksInfoCell, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText4));
|
||||
// themeDescriptions.add(new ThemeDescription(manageLinksInfoCell, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText4));
|
||||
|
||||
themeDescriptions.add(new ThemeDescription(adminedInfoCell, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow));
|
||||
themeDescriptions.add(new ThemeDescription(adminnedChannelsLayout, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
|
||||
themeDescriptions.add(new ThemeDescription(privateTextView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
themeDescriptions.add(new ThemeDescription(privateTextView, 0, new Class[]{TextBlockCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
themeDescriptions.add(new ThemeDescription(loadingAdminedCell, 0, new Class[]{LoadingCell.class}, new String[]{"progressBar"}, null, null, null, Theme.key_progressCircle));
|
||||
themeDescriptions.add(new ThemeDescription(radioButtonCell1, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
themeDescriptions.add(new ThemeDescription(radioButtonCell1, ThemeDescription.FLAG_CHECKBOX, new Class[]{RadioButtonCell.class}, new String[]{"radioButton"}, null, null, null, Theme.key_radioBackground));
|
||||
|
@ -793,15 +790,6 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
themeDescriptions.add(new ThemeDescription(radioButtonCell2, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{RadioButtonCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
themeDescriptions.add(new ThemeDescription(radioButtonCell2, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{RadioButtonCell.class}, new String[]{"valueTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText2));
|
||||
|
||||
themeDescriptions.add(new ThemeDescription(copyCell, 0, new Class[]{TextSettingsCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
themeDescriptions.add(new ThemeDescription(copyCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
|
||||
themeDescriptions.add(new ThemeDescription(revokeCell, 0, new Class[]{TextSettingsCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
themeDescriptions.add(new ThemeDescription(revokeCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
|
||||
themeDescriptions.add(new ThemeDescription(shareCell, 0, new Class[]{TextSettingsCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
themeDescriptions.add(new ThemeDescription(shareCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
|
||||
themeDescriptions.add(new ThemeDescription(adminnedChannelsLayout, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{AdminedChannelCell.class}, new String[]{"nameTextView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
themeDescriptions.add(new ThemeDescription(adminnedChannelsLayout, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{AdminedChannelCell.class}, new String[]{"statusTextView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText));
|
||||
themeDescriptions.add(new ThemeDescription(adminnedChannelsLayout, ThemeDescription.FLAG_LINKCOLOR, new Class[]{AdminedChannelCell.class}, new String[]{"statusTextView"}, null, null, null, Theme.key_windowBackgroundWhiteLinkText));
|
||||
|
@ -815,6 +803,11 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
|
|||
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundBlue));
|
||||
themeDescriptions.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_avatar_backgroundPink));
|
||||
|
||||
// themeDescriptions.add(new ThemeDescription(manageLinksTextView, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
|
||||
// themeDescriptions.add(new ThemeDescription(manageLinksTextView, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
|
||||
// themeDescriptions.add(new ThemeDescription(manageLinksTextView, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon));
|
||||
|
||||
|
||||
return themeDescriptions;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package org.telegram.ui;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
|
@ -22,6 +24,7 @@ import android.text.TextPaint;
|
|||
import android.text.TextUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -36,9 +39,10 @@ import android.widget.LinearLayout;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
|
@ -86,6 +90,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
private ListAdapter listViewAdapter;
|
||||
private StickerEmptyView emptyView;
|
||||
private RecyclerListView listView;
|
||||
private LinearLayoutManager layoutManager;
|
||||
private SearchAdapter searchListViewAdapter;
|
||||
private ActionBarMenuItem searchItem;
|
||||
private ActionBarMenuItem doneItem;
|
||||
|
@ -150,7 +155,8 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
private int blockedEmptyRow;
|
||||
private int rowCount;
|
||||
private int selectType;
|
||||
private int lastEmptyViewRow;
|
||||
private int loadingUserCellRow;
|
||||
private int loadingHeaderRow;
|
||||
|
||||
private int delayResults;
|
||||
|
||||
|
@ -170,7 +176,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
public final static int TYPE_ADMIN = 1;
|
||||
public final static int TYPE_USERS = 2;
|
||||
public final static int TYPE_KICKED = 3;
|
||||
private boolean openTransitionEnded;
|
||||
private boolean openTransitionStarted;
|
||||
private FlickerLoadingView flickerLoadingView;
|
||||
private View progressBar;
|
||||
|
||||
|
@ -186,6 +192,10 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
default void didSelectUser(int uid) {
|
||||
|
||||
}
|
||||
|
||||
default void didUserKicked(int userId) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class ChooseView extends View {
|
||||
|
@ -454,7 +464,8 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
slowmodeSelectRow = -1;
|
||||
slowmodeInfoRow = -1;
|
||||
loadingProgressRow = -1;
|
||||
lastEmptyViewRow = -1;
|
||||
loadingUserCellRow = -1;
|
||||
loadingHeaderRow = -1;
|
||||
|
||||
rowCount = 0;
|
||||
if (type == TYPE_KICKED) {
|
||||
|
@ -486,9 +497,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
addNewRow = rowCount++;
|
||||
}
|
||||
|
||||
if (loadingUsers && !firstLoaded) {
|
||||
//loadingProgressRow = rowCount++;
|
||||
} else {
|
||||
if (!(loadingUsers && !firstLoaded)) {
|
||||
if (!participants.isEmpty()) {
|
||||
participantsStartRow = rowCount;
|
||||
rowCount += participants.size();
|
||||
|
@ -497,18 +506,19 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
if (addNewRow != -1 || participantsStartRow != -1) {
|
||||
addNewSectionRow = rowCount++;
|
||||
}
|
||||
lastEmptyViewRow = rowCount++;
|
||||
} else if (!firstLoaded) {
|
||||
if (info != null && info.banned_count > 0) {
|
||||
loadingUserCellRow = rowCount++;
|
||||
}
|
||||
}
|
||||
} else if (type == TYPE_BANNED) {
|
||||
if (ChatObject.canBlockUsers(currentChat)) {
|
||||
addNewRow = rowCount++;
|
||||
if (!participants.isEmpty()) {
|
||||
if (!participants.isEmpty() || (loadingUsers && !firstLoaded && (info != null && info.kicked_count > 0))) {
|
||||
participantsInfoRow = rowCount++;
|
||||
}
|
||||
}
|
||||
if (loadingUsers && !firstLoaded) {
|
||||
// loadingProgressRow = rowCount++;
|
||||
} else {
|
||||
if (!(loadingUsers && !firstLoaded)) {
|
||||
if (!participants.isEmpty()) {
|
||||
restricted1SectionRow = rowCount++;
|
||||
participantsStartRow = rowCount;
|
||||
|
@ -518,14 +528,16 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
if (participantsStartRow != -1) {
|
||||
if (participantsInfoRow == -1) {
|
||||
participantsInfoRow = rowCount++;
|
||||
lastEmptyViewRow = rowCount++;
|
||||
} else {
|
||||
addNewSectionRow = rowCount++;
|
||||
}
|
||||
} else {
|
||||
restricted1SectionRow = rowCount++;
|
||||
blockedEmptyRow = rowCount++;
|
||||
}
|
||||
lastEmptyViewRow = rowCount++;
|
||||
} else if (!firstLoaded) {
|
||||
restricted1SectionRow = rowCount++;
|
||||
loadingUserCellRow = rowCount++;
|
||||
}
|
||||
} else if (type == TYPE_ADMIN) {
|
||||
if (ChatObject.isChannel(currentChat) && currentChat.megagroup && (info == null || info.participants_count <= 200)) {
|
||||
|
@ -536,28 +548,21 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
if (ChatObject.canAddAdmins(currentChat)) {
|
||||
addNewRow = rowCount++;
|
||||
}
|
||||
if (loadingUsers && !firstLoaded) {
|
||||
// loadingProgressRow = rowCount++;
|
||||
} else {
|
||||
if (!(loadingUsers && !firstLoaded)) {
|
||||
if (!participants.isEmpty()) {
|
||||
participantsStartRow = rowCount;
|
||||
rowCount += participants.size();
|
||||
participantsEndRow = rowCount;
|
||||
}
|
||||
participantsInfoRow = rowCount++;
|
||||
lastEmptyViewRow = rowCount++;
|
||||
} else if (!firstLoaded) {
|
||||
loadingUserCellRow = rowCount++;
|
||||
}
|
||||
} else if (type == TYPE_USERS) {
|
||||
if (selectType == 0 && ChatObject.canAddUsers(currentChat)) {
|
||||
/*if (ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_INVITE) && (!ChatObject.isChannel(currentChat) || currentChat.megagroup || TextUtils.isEmpty(currentChat.username))) {
|
||||
addNew2Row = rowCount++;
|
||||
addNewSectionRow = rowCount++;
|
||||
}*/
|
||||
addNewRow = rowCount++;
|
||||
}
|
||||
if (loadingUsers && !firstLoaded) {
|
||||
// loadingProgressRow = rowCount++;
|
||||
} else {
|
||||
if (!(loadingUsers && !firstLoaded)) {
|
||||
boolean hasAnyOther = false;
|
||||
if (!contacts.isEmpty()) {
|
||||
contactsHeaderRow = rowCount++;
|
||||
|
@ -583,8 +588,12 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
}
|
||||
if (rowCount != 0) {
|
||||
participantsInfoRow = rowCount++;
|
||||
lastEmptyViewRow = rowCount++;
|
||||
}
|
||||
} else if (!firstLoaded) {
|
||||
if (selectType == 0) {
|
||||
loadingHeaderRow = rowCount++;
|
||||
}
|
||||
loadingUserCellRow = rowCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -660,6 +669,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
public void onSearchCollapse() {
|
||||
searchListViewAdapter.searchUsers(null);
|
||||
searching = false;
|
||||
listView.setAnimateEmptyView(false, 0);
|
||||
listView.setAdapter(listViewAdapter);
|
||||
listViewAdapter.notifyDataSetChanged();
|
||||
listView.setFastScrollVisible(true);
|
||||
|
@ -678,6 +688,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
int oldItemsCount = listView.getAdapter() == null ? 0 : listView.getAdapter().getItemCount();
|
||||
searchListViewAdapter.searchUsers(text);
|
||||
if (TextUtils.isEmpty(text) && listView != null && listView.getAdapter() != listViewAdapter) {
|
||||
listView.setAnimateEmptyView(false, 0);
|
||||
listView.setAdapter(listViewAdapter);
|
||||
if (oldItemsCount == 0) {
|
||||
showItemsAnimated(0);
|
||||
|
@ -698,8 +709,13 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
}
|
||||
}
|
||||
|
||||
fragmentView = new FrameLayout(context);
|
||||
fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
|
||||
fragmentView = new FrameLayout(context) {
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.drawColor(Theme.getColor(listView.getAdapter() == searchListViewAdapter ? Theme.key_windowBackgroundWhite : Theme.key_windowBackgroundGray));
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
};
|
||||
FrameLayout frameLayout = (FrameLayout) fragmentView;
|
||||
|
||||
FrameLayout progressLayout = new FrameLayout(context);
|
||||
|
@ -711,24 +727,66 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
|
||||
progressBar = new RadialProgressView(context);
|
||||
progressLayout.addView(progressBar, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
|
||||
frameLayout.addView(progressLayout);
|
||||
|
||||
if (type == 3) {
|
||||
flickerLoadingView.setVisibility(View.GONE);
|
||||
} else {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
flickerLoadingView.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
emptyView = new StickerEmptyView(context, progressLayout, StickerEmptyView.STICKER_TYPE_SEARCH);
|
||||
emptyView.title.setText(LocaleController.getString("NoResult", R.string.NoResult));
|
||||
emptyView.subtitle.setText(LocaleController.getString("SearchEmptyViewFilteredSubtitle2", R.string.SearchEmptyViewFilteredSubtitle2));
|
||||
emptyView.setVisibility(View.GONE);
|
||||
emptyView.setAnimateLayoutChange(true);
|
||||
emptyView.showProgress(true, false);
|
||||
frameLayout.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
|
||||
listView = new RecyclerListView(context);
|
||||
listView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
|
||||
((SimpleItemAnimator) listView.getItemAnimator()).setSupportsChangeAnimations(false);
|
||||
frameLayout.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
emptyView.addView(progressLayout,0);
|
||||
|
||||
listView = new RecyclerListView(context) {
|
||||
@Override
|
||||
public void invalidate() {
|
||||
super.invalidate();
|
||||
fragmentView.invalidate();
|
||||
}
|
||||
};
|
||||
listView.setLayoutManager(layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) {
|
||||
@Override
|
||||
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
|
||||
if (!firstLoaded && type != TYPE_KICKED) {
|
||||
return 0;
|
||||
}
|
||||
return super.scrollVerticallyBy(dy, recycler, state);
|
||||
}
|
||||
});
|
||||
DefaultItemAnimator itemAnimator = new DefaultItemAnimator() {
|
||||
|
||||
@Override
|
||||
protected long getAddAnimationDelay(long removeDuration, long moveDuration, long changeDuration) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getMoveAnimationDelay() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMoveDuration() {
|
||||
return 220;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRemoveDuration() {
|
||||
return 220;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAddDuration() {
|
||||
return 220;
|
||||
}
|
||||
};
|
||||
listView.setItemAnimator(itemAnimator);
|
||||
itemAnimator.setSupportsChangeAnimations(false);
|
||||
listView.setAnimateEmptyView(true, 0);
|
||||
listView.setAdapter(listViewAdapter = new ListAdapter(context));
|
||||
listView.setVerticalScrollbarPosition(LocaleController.isRTL ? RecyclerListView.SCROLLBAR_POSITION_LEFT : RecyclerListView.SCROLLBAR_POSITION_RIGHT);
|
||||
frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
|
@ -744,6 +802,35 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
bundle.putInt("selectType", type == TYPE_BANNED ? 2 : 3);
|
||||
ChatUsersActivity fragment = new ChatUsersActivity(bundle);
|
||||
fragment.setInfo(info);
|
||||
fragment.setDelegate(new ChatUsersActivityDelegate() {
|
||||
|
||||
@Override
|
||||
public void didAddParticipantToList(int uid, TLObject participant) {
|
||||
if (participantsMap.get(uid) == null) {
|
||||
DiffCallback diffCallback = saveState();
|
||||
participants.add(participant);
|
||||
participantsMap.put(uid, participant);
|
||||
sortUsers(participants);
|
||||
updateListAnimated(diffCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didUserKicked(int uid) {
|
||||
if (participantsMap.get(uid) == null) {
|
||||
DiffCallback diffCallback = saveState();
|
||||
TLRPC.TL_channelParticipantBanned chatParticipant = new TLRPC.TL_channelParticipantBanned();
|
||||
chatParticipant.user_id = uid;
|
||||
chatParticipant.date = getConnectionsManager().getCurrentTime();
|
||||
chatParticipant.kicked_by = getAccountInstance().getUserConfig().clientUserId;
|
||||
info.kicked_count++;
|
||||
participants.add(chatParticipant);
|
||||
participantsMap.put(uid, chatParticipant);
|
||||
sortUsers(participants);
|
||||
updateListAnimated(diffCallback);
|
||||
}
|
||||
}
|
||||
});
|
||||
presentFragment(fragment);
|
||||
} else if (type == TYPE_ADMIN) {
|
||||
Bundle bundle = new Bundle();
|
||||
|
@ -755,21 +842,11 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
@Override
|
||||
public void didAddParticipantToList(int uid, TLObject participant) {
|
||||
if (participant != null && participantsMap.get(uid) == null) {
|
||||
DiffCallback diffCallback = saveState();
|
||||
participants.add(participant);
|
||||
Collections.sort(participants, (lhs, rhs) -> {
|
||||
int type1 = getChannelAdminParticipantType(lhs);
|
||||
int type2 = getChannelAdminParticipantType(rhs);
|
||||
if (type1 > type2) {
|
||||
return 1;
|
||||
} else if (type1 < type2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
updateRows();
|
||||
if (listViewAdapter != null) {
|
||||
listViewAdapter.notifyDataSetChanged();
|
||||
}
|
||||
participantsMap.put(uid, participant);
|
||||
sortAdmins(participants);
|
||||
updateListAnimated(diffCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -788,6 +865,20 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
|
||||
if (participantsMap.get(uid) == null) {
|
||||
DiffCallback diffCallback = saveState();
|
||||
TLRPC.TL_channelParticipantAdmin chatParticipant = new TLRPC.TL_channelParticipantAdmin();
|
||||
chatParticipant.user_id = user.id;
|
||||
chatParticipant.date = getConnectionsManager().getCurrentTime();
|
||||
chatParticipant.promoted_by = getAccountInstance().getUserConfig().clientUserId;
|
||||
participants.add(chatParticipant);
|
||||
participantsMap.put(user.id, chatParticipant);
|
||||
|
||||
sortAdmins(participants);
|
||||
updateListAnimated(diffCallback);
|
||||
}
|
||||
}
|
||||
});
|
||||
fragment.setInfo(info);
|
||||
|
@ -802,10 +893,30 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
fragment.setDelegate(new GroupCreateActivity.ContactsAddActivityDelegate() {
|
||||
@Override
|
||||
public void didSelectUsers(ArrayList<TLRPC.User> users, int fwdCount) {
|
||||
DiffCallback savedState = saveState();
|
||||
ArrayList<TLObject> array = contactsMap != null && contactsMap.size() != 0 ? contacts : participants;
|
||||
SparseArray<TLObject> map = contactsMap != null && contactsMap.size() != 0 ? contactsMap : participantsMap;
|
||||
int k = 0;
|
||||
for (int a = 0, N = users.size(); a < N; a++) {
|
||||
TLRPC.User user = users.get(a);
|
||||
getMessagesController().addUserToChat(chatId, user, fwdCount, null, ChatUsersActivity.this, null);
|
||||
getMessagesController().putUser(user, false);
|
||||
|
||||
if (map.get(user.id) == null) {
|
||||
TLRPC.ChatParticipant participant = new TLRPC.TL_chatParticipant();
|
||||
participant.inviter_id = getUserConfig().getClientUserId();
|
||||
participant.user_id = user.id;
|
||||
participant.date = getConnectionsManager().getCurrentTime();
|
||||
|
||||
array.add(k, participant);
|
||||
k++;
|
||||
map.put(user.id, participant);
|
||||
}
|
||||
}
|
||||
if (array == participants) {
|
||||
sortAdmins(participants);
|
||||
}
|
||||
updateListAnimated(savedState);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1081,7 +1192,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
updateRows();
|
||||
|
||||
listView.setEmptyView(emptyView);
|
||||
listView.setAnimateEmptyView(true, 0);
|
||||
listView.setAnimateEmptyView(false, 0);
|
||||
|
||||
if (needOpenSearch) {
|
||||
searchItem.openSearch(false);
|
||||
|
@ -1090,10 +1201,40 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
return fragmentView;
|
||||
}
|
||||
|
||||
private void sortAdmins(ArrayList<TLObject> participants) {
|
||||
Collections.sort(participants, (lhs, rhs) -> {
|
||||
int type1 = getChannelAdminParticipantType(lhs);
|
||||
int type2 = getChannelAdminParticipantType(rhs);
|
||||
if (type1 > type2) {
|
||||
return 1;
|
||||
} else if (type1 < type2) {
|
||||
return -1;
|
||||
}
|
||||
if (lhs instanceof TLRPC.ChannelParticipant && rhs instanceof TLRPC.ChannelParticipant) {
|
||||
return ((TLRPC.ChannelParticipant) lhs).user_id - ((TLRPC.ChannelParticipant) rhs).user_id;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
private void showItemsAnimated(int from) {
|
||||
if (isPaused || !openTransitionEnded) {
|
||||
if (isPaused || !openTransitionStarted || (listView.getAdapter() == listViewAdapter && firstLoaded)) {
|
||||
return;
|
||||
}
|
||||
View progressView = null;
|
||||
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||
View child = listView.getChildAt(i);
|
||||
if (child instanceof FlickerLoadingView) {
|
||||
progressView = child;
|
||||
}
|
||||
}
|
||||
final View finalProgressView = progressView;
|
||||
if (progressView != null) {
|
||||
listView.removeView(progressView);
|
||||
from--;
|
||||
}
|
||||
int finalFrom = from;
|
||||
|
||||
listView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
|
@ -1102,7 +1243,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
for (int i = 0; i < n; i++) {
|
||||
View child = listView.getChildAt(i);
|
||||
if (listView.getChildAdapterPosition(child) < from) {
|
||||
if (child == finalProgressView || listView.getChildAdapterPosition(child) < finalFrom) {
|
||||
continue;
|
||||
}
|
||||
child.setAlpha(0);
|
||||
|
@ -1113,6 +1254,25 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
a.setDuration(200);
|
||||
animatorSet.playTogether(a);
|
||||
}
|
||||
|
||||
if (finalProgressView != null && finalProgressView.getParent() == null) {
|
||||
listView.addView(finalProgressView);
|
||||
RecyclerView.LayoutManager layoutManager = listView.getLayoutManager();
|
||||
if (layoutManager != null) {
|
||||
layoutManager.ignoreView(finalProgressView);
|
||||
Animator animator = ObjectAnimator.ofFloat(finalProgressView, View.ALPHA, finalProgressView.getAlpha(), 0);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
finalProgressView.setAlpha(1f);
|
||||
layoutManager.stopIgnoringView(finalProgressView);
|
||||
listView.removeView(finalProgressView);
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
|
||||
animatorSet.start();
|
||||
return true;
|
||||
}
|
||||
|
@ -1195,16 +1355,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
creator.user_id = user.id;
|
||||
participantsMap.put(user.id, creator);
|
||||
participants.add(creator);
|
||||
Collections.sort(participants, (lhs, rhs) -> {
|
||||
int type1 = getChannelAdminParticipantType(lhs);
|
||||
int type2 = getChannelAdminParticipantType(rhs);
|
||||
if (type1 > type2) {
|
||||
return 1;
|
||||
} else if (type1 < type2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
sortAdmins(participants);
|
||||
updateRows();
|
||||
}
|
||||
listViewAdapter.notifyDataSetChanged();
|
||||
|
@ -1306,6 +1457,8 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
}
|
||||
if (delegate != null && rights == 1) {
|
||||
delegate.didSelectUser(user_id);
|
||||
} else if (delegate != null) {
|
||||
delegate.didAddParticipantToList(user_id, participant);
|
||||
}
|
||||
if (removeFragment) {
|
||||
removeSelfFromStack();
|
||||
|
@ -1326,11 +1479,13 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
}
|
||||
TLRPC.User user = getMessagesController().getUser(userId);
|
||||
getMessagesController().deleteUserFromChat(chatId, user, null);
|
||||
if (delegate != null) {
|
||||
delegate.didUserKicked(userId);
|
||||
}
|
||||
finishFragment();
|
||||
}
|
||||
|
||||
private TLObject getAnyParticipant(int userId) {
|
||||
boolean updated = false;
|
||||
for (int a = 0; a < 3; a++) {
|
||||
SparseArray<TLObject> map;
|
||||
if (a == 0) {
|
||||
|
@ -1360,6 +1515,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
|
||||
private void removeParticipants(int userId) {
|
||||
boolean updated = false;
|
||||
DiffCallback savedState = saveState();
|
||||
for (int a = 0; a < 3; a++) {
|
||||
SparseArray<TLObject> map;
|
||||
ArrayList<TLObject> arrayList;
|
||||
|
@ -1378,11 +1534,13 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
map.remove(userId);
|
||||
arrayList.remove(p);
|
||||
updated = true;
|
||||
if (type == TYPE_BANNED) {
|
||||
info.kicked_count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
updateRows();
|
||||
listViewAdapter.notifyDataSetChanged();
|
||||
updateListAnimated(savedState);
|
||||
}
|
||||
if (listView.getAdapter() == searchListViewAdapter) {
|
||||
searchListViewAdapter.removeUserId(userId);
|
||||
|
@ -1998,7 +2156,6 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
req.offset = offset;
|
||||
req.limit = count;
|
||||
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
||||
resumeDelayedFragmentAnimation();
|
||||
if (error == null) {
|
||||
TLRPC.TL_channels_channelParticipants res = (TLRPC.TL_channels_channelParticipants) response;
|
||||
if (type == TYPE_ADMIN) {
|
||||
|
@ -2060,82 +2217,80 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
}
|
||||
try {
|
||||
if ((type == TYPE_BANNED || type == TYPE_KICKED || type == TYPE_USERS) && currentChat != null && currentChat.megagroup && info instanceof TLRPC.TL_channelFull && info.participants_count <= 200) {
|
||||
int currentTime = getConnectionsManager().getCurrentTime();
|
||||
Collections.sort(objects, (lhs, rhs) -> {
|
||||
TLRPC.ChannelParticipant p1 = (TLRPC.ChannelParticipant) lhs;
|
||||
TLRPC.ChannelParticipant p2 = (TLRPC.ChannelParticipant) rhs;
|
||||
TLRPC.User user1 = getMessagesController().getUser(p1.user_id);
|
||||
TLRPC.User user2 = getMessagesController().getUser(p2.user_id);
|
||||
int status1 = 0;
|
||||
int status2 = 0;
|
||||
if (user1 != null && user1.status != null) {
|
||||
if (user1.self) {
|
||||
status1 = currentTime + 50000;
|
||||
} else {
|
||||
status1 = user1.status.expires;
|
||||
}
|
||||
}
|
||||
if (user2 != null && user2.status != null) {
|
||||
if (user2.self) {
|
||||
status2 = currentTime + 50000;
|
||||
} else {
|
||||
status2 = user2.status.expires;
|
||||
}
|
||||
}
|
||||
if (status1 > 0 && status2 > 0) {
|
||||
if (status1 > status2) {
|
||||
return 1;
|
||||
} else if (status1 < status2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else if (status1 < 0 && status2 < 0) {
|
||||
if (status1 > status2) {
|
||||
return 1;
|
||||
} else if (status1 < status2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else if (status1 < 0 && status2 > 0 || status1 == 0 && status2 != 0) {
|
||||
return -1;
|
||||
} else if (status2 < 0 && status1 > 0 || status2 == 0 && status1 != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
sortUsers(objects);
|
||||
} else if (type == TYPE_ADMIN) {
|
||||
Collections.sort(participants, (lhs, rhs) -> {
|
||||
int type1 = getChannelAdminParticipantType(lhs);
|
||||
int type2 = getChannelAdminParticipantType(rhs);
|
||||
if (type1 > type2) {
|
||||
return 1;
|
||||
} else if (type1 < type2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
sortAdmins(participants);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
if (type != TYPE_USERS || delayResults <= 0) {
|
||||
showItemsAnimated(listViewAdapter != null ? listViewAdapter.getItemCount() : 0);
|
||||
loadingUsers = false;
|
||||
firstLoaded = true;
|
||||
showItemsAnimated(listViewAdapter != null ? listViewAdapter.getItemCount() : 0);
|
||||
}
|
||||
updateRows();
|
||||
if (listViewAdapter != null) {
|
||||
listView.setAnimateEmptyView(openTransitionStarted, 0);
|
||||
listViewAdapter.notifyDataSetChanged();
|
||||
|
||||
if (emptyView != null && listViewAdapter.getItemCount() == 0 && firstLoaded) {
|
||||
emptyView.showProgress(false, true);
|
||||
}
|
||||
}
|
||||
resumeDelayedFragmentAnimation();
|
||||
}));
|
||||
getConnectionsManager().bindRequestToGuid(reqId, classGuid);
|
||||
}
|
||||
}
|
||||
|
||||
private void sortUsers(ArrayList<TLObject> objects) {
|
||||
int currentTime = getConnectionsManager().getCurrentTime();
|
||||
Collections.sort(objects, (lhs, rhs) -> {
|
||||
TLRPC.ChannelParticipant p1 = (TLRPC.ChannelParticipant) lhs;
|
||||
TLRPC.ChannelParticipant p2 = (TLRPC.ChannelParticipant) rhs;
|
||||
TLRPC.User user1 = getMessagesController().getUser(p1.user_id);
|
||||
TLRPC.User user2 = getMessagesController().getUser(p2.user_id);
|
||||
int status1 = 0;
|
||||
int status2 = 0;
|
||||
if (user1 != null && user1.status != null) {
|
||||
if (user1.self) {
|
||||
status1 = currentTime + 50000;
|
||||
} else {
|
||||
status1 = user1.status.expires;
|
||||
}
|
||||
}
|
||||
if (user2 != null && user2.status != null) {
|
||||
if (user2.self) {
|
||||
status2 = currentTime + 50000;
|
||||
} else {
|
||||
status2 = user2.status.expires;
|
||||
}
|
||||
}
|
||||
if (status1 > 0 && status2 > 0) {
|
||||
if (status1 > status2) {
|
||||
return 1;
|
||||
} else if (status1 < status2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else if (status1 < 0 && status2 < 0) {
|
||||
if (status1 > status2) {
|
||||
return 1;
|
||||
} else if (status1 < status2) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else if (status1 < 0 && status2 > 0 || status1 == 0 && status2 != 0) {
|
||||
return -1;
|
||||
} else if (status2 < 0 && status1 > 0 || status2 == 0 && status1 != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -2167,10 +2322,18 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
return selectType;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected void onTransitionAnimationStart(boolean isOpen, boolean backward) {
|
||||
// super.onTransitionAnimationStart(isOpen, backward);
|
||||
// if (isOpen) {
|
||||
// openTransitionStarted = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected void onTransitionAnimationEnd(boolean isOpen, boolean backward) {
|
||||
if (isOpen) {
|
||||
openTransitionEnded = true;
|
||||
openTransitionStarted = true;
|
||||
}
|
||||
if (isOpen && !backward && needOpenSearch) {
|
||||
searchItem.getSearchField().requestFocus();
|
||||
|
@ -2409,6 +2572,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
globalStartRow = -1;
|
||||
}
|
||||
if (searching && listView != null && listView.getAdapter() != searchListViewAdapter) {
|
||||
listView.setAnimateEmptyView(true, 0);
|
||||
listView.setAdapter(searchListViewAdapter);
|
||||
listView.setFastScrollVisible(false);
|
||||
listView.setVerticalScrollBarEnabled(true);
|
||||
|
@ -2652,9 +2816,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (type == TYPE_KICKED && loadingUsers && !firstLoaded) {
|
||||
/* if (type == TYPE_KICKED && loadingUsers && !firstLoaded) {
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
@ -2672,27 +2836,14 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
view = manageChatUserCell;
|
||||
break;
|
||||
case 1:
|
||||
view = new TextInfoPrivacyCell(mContext) {
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
};
|
||||
view = new TextInfoPrivacyCell(mContext);
|
||||
break;
|
||||
case 2:
|
||||
view = new ManageChatTextCell(mContext);
|
||||
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
|
||||
break;
|
||||
case 3:
|
||||
view = new ShadowSectionCell(mContext) {
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
};
|
||||
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
view = new ShadowSectionCell(mContext);
|
||||
break;
|
||||
case 4:
|
||||
view = new FrameLayout(mContext) {
|
||||
|
@ -2701,12 +2852,6 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) - AndroidUtilities.dp(56), MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
};
|
||||
FrameLayout frameLayout = (FrameLayout) view;
|
||||
frameLayout.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
|
||||
|
@ -2758,28 +2903,20 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
break;
|
||||
case 8:
|
||||
view = new GraySectionCell(mContext);
|
||||
view.setBackground(null);
|
||||
break;
|
||||
case 10:
|
||||
view = new LoadingCell(mContext, AndroidUtilities.dp(40), AndroidUtilities.dp(120));
|
||||
break;
|
||||
case 11:
|
||||
view = new View(mContext) {
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int h = 0;
|
||||
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||
if (listView.getChildAt(i) != this) {
|
||||
h += listView.getChildAt(i).getMeasuredHeight();
|
||||
}
|
||||
}
|
||||
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), Math.max(0, listView.getMeasuredHeight() - h));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
}
|
||||
};
|
||||
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(mContext);
|
||||
flickerLoadingView.setIsSingleCell(true);
|
||||
flickerLoadingView.setViewType(FlickerLoadingView.USERS_TYPE);
|
||||
flickerLoadingView.showDate(false);
|
||||
flickerLoadingView.setPaddingLeft(AndroidUtilities.dp(5));
|
||||
flickerLoadingView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
|
||||
flickerLoadingView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
view = flickerLoadingView;
|
||||
break;
|
||||
case 9:
|
||||
default:
|
||||
|
@ -3031,6 +3168,16 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
} else {
|
||||
sectionCell.setText(LocaleController.getString("GroupContacts", R.string.GroupContacts));
|
||||
}
|
||||
} else if (position == loadingHeaderRow) {
|
||||
sectionCell.setText("");
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
FlickerLoadingView flickerLoadingView = (FlickerLoadingView) holder.itemView;
|
||||
if (type == TYPE_BANNED) {
|
||||
flickerLoadingView.setItemsCount(info == null ? 1 : info.kicked_count);
|
||||
} else {
|
||||
flickerLoadingView.setItemsCount(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3064,13 +3211,13 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
} else if (position == changeInfoRow || position == addUsersRow || position == pinMessagesRow || position == sendMessagesRow ||
|
||||
position == sendMediaRow || position == sendStickersRow || position == embedLinksRow || position == sendPollsRow) {
|
||||
return 7;
|
||||
} else if (position == membersHeaderRow || position == contactsHeaderRow || position == botHeaderRow) {
|
||||
} else if (position == membersHeaderRow || position == contactsHeaderRow || position == botHeaderRow || position == loadingHeaderRow) {
|
||||
return 8;
|
||||
} else if (position == slowmodeSelectRow) {
|
||||
return 9;
|
||||
} else if (position == loadingProgressRow) {
|
||||
return 10;
|
||||
} else if (position == lastEmptyViewRow) {
|
||||
} else if (position == loadingUserCellRow) {
|
||||
return 11;
|
||||
}
|
||||
return 0;
|
||||
|
@ -3088,6 +3235,143 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
|
|||
}
|
||||
}
|
||||
|
||||
public DiffCallback saveState() {
|
||||
DiffCallback diffCallback = new DiffCallback();
|
||||
diffCallback.oldRowCount = rowCount;
|
||||
|
||||
diffCallback.oldBotStartRow = botStartRow;
|
||||
diffCallback.oldBotEndRow = botEndRow;
|
||||
diffCallback.oldBots.clear();
|
||||
diffCallback.oldBots.addAll(bots);
|
||||
|
||||
diffCallback.oldContactsEndRow = contactsEndRow;
|
||||
diffCallback.oldContactsStartRow = contactsStartRow;
|
||||
diffCallback.oldContacts.clear();
|
||||
diffCallback.oldContacts.addAll(contacts);
|
||||
|
||||
diffCallback.oldParticipantsStartRow = participantsStartRow;
|
||||
diffCallback.oldParticipantsEndRow = participantsEndRow;
|
||||
diffCallback.oldParticipants.clear();
|
||||
diffCallback.oldParticipants.addAll(participants);
|
||||
|
||||
diffCallback.fillPositions(diffCallback.oldPositionToItem);
|
||||
return diffCallback;
|
||||
}
|
||||
|
||||
public void updateListAnimated(DiffCallback savedState) {
|
||||
if (listViewAdapter == null) {
|
||||
updateRows();
|
||||
return;
|
||||
}
|
||||
updateRows();
|
||||
savedState.fillPositions(savedState.newPositionToItem);
|
||||
DiffUtil.calculateDiff(savedState).dispatchUpdatesTo(listViewAdapter);
|
||||
if (listView != null && layoutManager != null && listView.getChildCount() > 0) {
|
||||
View view = null;
|
||||
int position = -1;
|
||||
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||
position = listView.getChildAdapterPosition(listView.getChildAt(i));
|
||||
if (position != RecyclerListView.NO_POSITION) {
|
||||
view = listView.getChildAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (view != null) {
|
||||
layoutManager.scrollToPositionWithOffset(position, view.getTop() - listView.getPaddingTop());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DiffCallback extends DiffUtil.Callback {
|
||||
|
||||
int oldRowCount;
|
||||
SparseIntArray oldPositionToItem = new SparseIntArray();
|
||||
SparseIntArray newPositionToItem = new SparseIntArray();
|
||||
|
||||
int oldParticipantsStartRow;
|
||||
int oldParticipantsEndRow;
|
||||
int oldContactsStartRow;
|
||||
int oldContactsEndRow;
|
||||
int oldBotStartRow;
|
||||
int oldBotEndRow;
|
||||
|
||||
private ArrayList<TLObject> oldParticipants = new ArrayList<>();
|
||||
private ArrayList<TLObject> oldBots = new ArrayList<>();
|
||||
private ArrayList<TLObject> oldContacts = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public int getOldListSize() {
|
||||
return oldRowCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNewListSize() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
|
||||
if (oldItemPosition >= oldBotStartRow && oldItemPosition < oldBotEndRow && newItemPosition >= botStartRow && newItemPosition < botEndRow) {
|
||||
return oldBots.get(oldItemPosition - oldBotStartRow).equals(bots.get(newItemPosition - botStartRow));
|
||||
} else if (oldItemPosition >= oldContactsStartRow && oldItemPosition < oldContactsEndRow && newItemPosition >= contactsStartRow && newItemPosition < contactsEndRow) {
|
||||
return oldContacts.get(oldItemPosition - oldContactsStartRow).equals(contacts.get(newItemPosition - contactsStartRow));
|
||||
} else if (oldItemPosition >= oldParticipantsStartRow && oldItemPosition < oldParticipantsEndRow && newItemPosition >= participantsStartRow && newItemPosition < participantsEndRow) {
|
||||
return oldParticipants.get(oldItemPosition - oldParticipantsStartRow).equals(participants.get(newItemPosition - participantsStartRow));
|
||||
}
|
||||
return oldPositionToItem.get(oldItemPosition) == newPositionToItem.get(newItemPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
|
||||
if (areItemsTheSame(oldItemPosition, newItemPosition)) {
|
||||
if (restricted1SectionRow == newItemPosition) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void fillPositions(SparseIntArray sparseIntArray) {
|
||||
sparseIntArray.clear();
|
||||
int pointer = 0;
|
||||
put(++pointer, recentActionsRow, sparseIntArray);
|
||||
put(++pointer, addNewRow, sparseIntArray);
|
||||
put(++pointer, addNew2Row, sparseIntArray);
|
||||
put(++pointer, addNewSectionRow, sparseIntArray);
|
||||
put(++pointer, restricted1SectionRow, sparseIntArray);
|
||||
put(++pointer, participantsDividerRow, sparseIntArray);
|
||||
put(++pointer, participantsDivider2Row, sparseIntArray);
|
||||
put(++pointer, participantsInfoRow, sparseIntArray);
|
||||
put(++pointer, blockedEmptyRow, sparseIntArray);
|
||||
put(++pointer, permissionsSectionRow, sparseIntArray);
|
||||
put(++pointer, sendMessagesRow, sparseIntArray);
|
||||
put(++pointer, sendMediaRow, sparseIntArray);
|
||||
put(++pointer, sendStickersRow, sparseIntArray);
|
||||
put(++pointer, sendPollsRow, sparseIntArray);
|
||||
put(++pointer, embedLinksRow, sparseIntArray);
|
||||
put(++pointer, addUsersRow, sparseIntArray);
|
||||
put(++pointer, pinMessagesRow, sparseIntArray);
|
||||
put(++pointer, changeInfoRow, sparseIntArray);
|
||||
put(++pointer, removedUsersRow, sparseIntArray);
|
||||
put(++pointer, contactsHeaderRow, sparseIntArray);
|
||||
put(++pointer, botHeaderRow, sparseIntArray);
|
||||
put(++pointer, membersHeaderRow, sparseIntArray);
|
||||
put(++pointer, slowmodeRow, sparseIntArray);
|
||||
put(++pointer, slowmodeSelectRow, sparseIntArray);
|
||||
put(++pointer, slowmodeInfoRow, sparseIntArray);
|
||||
put(++pointer, loadingProgressRow, sparseIntArray);
|
||||
put(++pointer, loadingUserCellRow, sparseIntArray);
|
||||
put(++pointer, loadingHeaderRow, sparseIntArray);
|
||||
}
|
||||
|
||||
private void put(int id, int position, SparseIntArray sparseIntArray) {
|
||||
if (position >= 0) {
|
||||
sparseIntArray.put(position, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<ThemeDescription> getThemeDescriptions() {
|
||||
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
|
||||
|
|
|
@ -113,7 +113,35 @@ public class AlertsCreator {
|
|||
if (error.code == 406 || error.text == null) {
|
||||
return null;
|
||||
}
|
||||
if (request instanceof TLRPC.TL_account_saveSecureValue || request instanceof TLRPC.TL_account_getAuthorizationForm) {
|
||||
if (request instanceof TLRPC.TL_messages_initHistoryImport || request instanceof TLRPC.TL_messages_checkHistoryImport || request instanceof TLRPC.TL_messages_startHistoryImport) {
|
||||
TLRPC.InputPeer peer;
|
||||
if (request instanceof TLRPC.TL_messages_initHistoryImport) {
|
||||
peer = ((TLRPC.TL_messages_initHistoryImport) request).peer;
|
||||
} else if (request instanceof TLRPC.TL_messages_startHistoryImport) {
|
||||
peer = ((TLRPC.TL_messages_startHistoryImport) request).peer;
|
||||
} else {
|
||||
peer = null;
|
||||
}
|
||||
if (error.text.contains("USER_IS_BLOCKED")) {
|
||||
showSimpleAlert(fragment, LocaleController.getString("ImportErrorTitle", R.string.ImportErrorTitle), LocaleController.getString("ImportErrorUserBlocked", R.string.ImportErrorUserBlocked));
|
||||
} else if (error.text.contains("USER_NOT_MUTUAL_CONTACT")) {
|
||||
showSimpleAlert(fragment, LocaleController.getString("ImportErrorTitle", R.string.ImportErrorTitle), LocaleController.getString("ImportMutualError", R.string.ImportMutualError));
|
||||
} else if (error.text.contains("IMPORT_PEER_TYPE_INVALID")) {
|
||||
if (peer instanceof TLRPC.TL_inputPeerUser) {
|
||||
showSimpleAlert(fragment, LocaleController.getString("ImportErrorTitle", R.string.ImportErrorTitle), LocaleController.getString("ImportErrorChatInvalidUser", R.string.ImportErrorChatInvalidUser));
|
||||
} else {
|
||||
showSimpleAlert(fragment, LocaleController.getString("ImportErrorTitle", R.string.ImportErrorTitle), LocaleController.getString("ImportErrorChatInvalidGroup", R.string.ImportErrorChatInvalidGroup));
|
||||
}
|
||||
} else if (error.text.contains("CHAT_ADMIN_REQUIRED")) {
|
||||
showSimpleAlert(fragment, LocaleController.getString("ImportErrorTitle", R.string.ImportErrorTitle), LocaleController.getString("ImportErrorNotAdmin", R.string.ImportErrorNotAdmin));
|
||||
} else if (error.text.startsWith("IMPORT_FORMAT")) {
|
||||
showSimpleAlert(fragment, LocaleController.getString("ImportErrorTitle", R.string.ImportErrorTitle), LocaleController.getString("ImportErrorFileFormatInvalid", R.string.ImportErrorFileFormatInvalid));
|
||||
} else if (error.text.contains("IMPORT_LANG_NOT_FOUND")) {
|
||||
showSimpleAlert(fragment, LocaleController.getString("ImportErrorTitle", R.string.ImportErrorTitle), LocaleController.getString("ImportErrorFileLang", R.string.ImportErrorFileLang));
|
||||
} else {
|
||||
showSimpleAlert(fragment, LocaleController.getString("ImportErrorTitle", R.string.ImportErrorTitle), LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred) + "\n" + error.text);
|
||||
}
|
||||
} else if (request instanceof TLRPC.TL_account_saveSecureValue || request instanceof TLRPC.TL_account_getAuthorizationForm) {
|
||||
if (error.text.contains("PHONE_NUMBER_INVALID")) {
|
||||
showSimpleAlert(fragment, LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber));
|
||||
} else if (error.text.startsWith("FLOOD_WAIT")) {
|
||||
|
@ -1044,11 +1072,97 @@ public class AlertsCreator {
|
|||
}
|
||||
}
|
||||
|
||||
public static void createClearOrDeleteDialogAlert(BaseFragment fragment, boolean clear, TLRPC.Chat chat, TLRPC.User user, boolean secret, MessagesStorage.BooleanCallback onProcessRunnable) {
|
||||
createClearOrDeleteDialogAlert(fragment, clear, false, false, chat, user, secret, onProcessRunnable);
|
||||
public static void createImportDialogAlert(BaseFragment fragment, String title, TLRPC.User user, TLRPC.Chat chat, Runnable onProcessRunnable) {
|
||||
if (fragment == null || fragment.getParentActivity() == null || chat == null && user == null) {
|
||||
return;
|
||||
}
|
||||
int account = fragment.getCurrentAccount();
|
||||
|
||||
Context context = fragment.getParentActivity();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
int selfUserId = UserConfig.getInstance(account).getClientUserId();
|
||||
|
||||
TextView messageTextView = new TextView(context);
|
||||
messageTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
|
||||
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
messageTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
|
||||
|
||||
FrameLayout frameLayout = new FrameLayout(context);
|
||||
builder.setView(frameLayout);
|
||||
|
||||
AvatarDrawable avatarDrawable = new AvatarDrawable();
|
||||
avatarDrawable.setTextSize(AndroidUtilities.dp(12));
|
||||
|
||||
BackupImageView imageView = new BackupImageView(context);
|
||||
imageView.setRoundRadius(AndroidUtilities.dp(20));
|
||||
frameLayout.addView(imageView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 22, 5, 22, 0));
|
||||
|
||||
TextView textView = new TextView(context);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
textView.setLines(1);
|
||||
textView.setMaxLines(1);
|
||||
textView.setSingleLine(true);
|
||||
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
textView.setText(LocaleController.formatString("ImportMessages", R.string.ImportMessages));
|
||||
|
||||
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 11, (LocaleController.isRTL ? 76 : 21), 0));
|
||||
frameLayout.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 57, 24, 9));
|
||||
|
||||
if (user != null) {
|
||||
if (UserObject.isReplyUser(user)) {
|
||||
avatarDrawable.setSmallSize(true);
|
||||
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
|
||||
imageView.setImage(null, null, avatarDrawable, user);
|
||||
} else if (user.id == selfUserId) {
|
||||
avatarDrawable.setSmallSize(true);
|
||||
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
|
||||
imageView.setImage(null, null, avatarDrawable, user);
|
||||
} else {
|
||||
avatarDrawable.setSmallSize(false);
|
||||
avatarDrawable.setInfo(user);
|
||||
imageView.setImage(ImageLocation.getForUser(user, false), "50_50", avatarDrawable, user);
|
||||
}
|
||||
} else {
|
||||
avatarDrawable.setInfo(chat);
|
||||
imageView.setImage(ImageLocation.getForChat(chat, false), "50_50", avatarDrawable, chat);
|
||||
}
|
||||
|
||||
if (chat != null) {
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("ImportToChatNoTitle", R.string.ImportToChatNoTitle, chat.title)));
|
||||
} else {
|
||||
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("ImportToChat", R.string.ImportToChat, title, chat.title)));
|
||||
}
|
||||
} else {
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("ImportToUserNoTitle", R.string.ImportToUserNoTitle, ContactsController.formatName(user.first_name, user.last_name))));
|
||||
} else {
|
||||
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("ImportToUser", R.string.ImportToUser, title, ContactsController.formatName(user.first_name, user.last_name))));
|
||||
}
|
||||
}
|
||||
|
||||
builder.setPositiveButton(LocaleController.getString("Import", R.string.Import), (dialogInterface, i) -> {
|
||||
if (onProcessRunnable != null) {
|
||||
onProcessRunnable.run();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
|
||||
AlertDialog alertDialog = builder.create();
|
||||
fragment.showDialog(alertDialog);
|
||||
}
|
||||
|
||||
public static void createClearOrDeleteDialogAlert(BaseFragment fragment, boolean clear, boolean admin, boolean second, TLRPC.Chat chat, TLRPC.User user, boolean secret, MessagesStorage.BooleanCallback onProcessRunnable) {
|
||||
public static void createClearOrDeleteDialogAlert(BaseFragment fragment, boolean clear, TLRPC.Chat chat, TLRPC.User user, boolean secret, MessagesStorage.BooleanCallback onProcessRunnable) {
|
||||
createClearOrDeleteDialogAlert(fragment, clear, false, false, chat, user, secret, false, onProcessRunnable);
|
||||
}
|
||||
|
||||
public static void createClearOrDeleteDialogAlert(BaseFragment fragment, boolean clear, TLRPC.Chat chat, TLRPC.User user, boolean secret, boolean checkDeleteForAll, MessagesStorage.BooleanCallback onProcessRunnable) {
|
||||
createClearOrDeleteDialogAlert(fragment, clear, chat != null && chat.creator, false, chat, user, secret, checkDeleteForAll, onProcessRunnable);
|
||||
}
|
||||
|
||||
public static void createClearOrDeleteDialogAlert(BaseFragment fragment, boolean clear, boolean admin, boolean second, TLRPC.Chat chat, TLRPC.User user, boolean secret, boolean checkDeleteForAll, MessagesStorage.BooleanCallback onProcessRunnable) {
|
||||
if (fragment == null || fragment.getParentActivity() == null || chat == null && user == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -1139,11 +1253,16 @@ public class AlertsCreator {
|
|||
}
|
||||
boolean canDeleteInbox = !secret && user != null && canRevokeInbox && revokeTimeLimit == 0x7fffffff;
|
||||
final boolean[] deleteForAll = new boolean[1];
|
||||
boolean deleteGroupForAll = false;
|
||||
|
||||
if (!second && canDeleteInbox && !UserObject.isDeleted(user)) {
|
||||
if (!second && (secret || canDeleteInbox) && !UserObject.isDeleted(user) || (deleteGroupForAll = checkDeleteForAll && !clear && chat != null && chat.creator && (!ChatObject.isChannel(chat) || chat.megagroup))) {
|
||||
cell[0] = new CheckBoxCell(context, 1);
|
||||
cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
if (clear) {
|
||||
if (secret) {
|
||||
cell[0].setText(LocaleController.formatString("DeleteForUser", R.string.DeleteForUser, UserObject.getFirstName(user)), "", false, false);
|
||||
} else if (deleteGroupForAll) {
|
||||
cell[0].setText(LocaleController.getString("DeleteGroupForAll", R.string.DeleteGroupForAll), "", false, false);
|
||||
} else if (clear) {
|
||||
cell[0].setText(LocaleController.formatString("ClearHistoryOptionAlso", R.string.ClearHistoryOptionAlso, UserObject.getFirstName(user)), "", false, false);
|
||||
} else {
|
||||
cell[0].setText(LocaleController.formatString("DeleteMessagesOptionAlso", R.string.DeleteMessagesOptionAlso, UserObject.getFirstName(user)), "", false, false);
|
||||
|
@ -1207,7 +1326,7 @@ public class AlertsCreator {
|
|||
if (admin) {
|
||||
if (ChatObject.isChannel(chat)) {
|
||||
if (chat.megagroup) {
|
||||
messageTextView.setText(LocaleController.getString("MegaDeleteAlert", R.string.MegaDeleteAlert));
|
||||
messageTextView.setText(LocaleController.getString("AreYouSureDeleteAndExit", R.string.AreYouSureDeleteAndExit));
|
||||
} else {
|
||||
messageTextView.setText(LocaleController.getString("ChannelDeleteAlert", R.string.ChannelDeleteAlert));
|
||||
}
|
||||
|
@ -1277,14 +1396,14 @@ public class AlertsCreator {
|
|||
}
|
||||
}
|
||||
builder.setPositiveButton(actionText, (dialogInterface, i) -> {
|
||||
if (!clearingCache && !second) {
|
||||
if (!clearingCache && !second && !secret) {
|
||||
if (UserObject.isUserSelf(user)) {
|
||||
createClearOrDeleteDialogAlert(fragment, clear, admin, true, chat, user, secret, onProcessRunnable);
|
||||
createClearOrDeleteDialogAlert(fragment, clear, admin, true, chat, user, false, checkDeleteForAll, onProcessRunnable);
|
||||
return;
|
||||
} else if (user != null && deleteForAll[0]) {
|
||||
MessagesStorage.getInstance(fragment.getCurrentAccount()).getMessagesCount(user.id, (count) -> {
|
||||
if (count >= 50) {
|
||||
createClearOrDeleteDialogAlert(fragment, clear, admin, true, chat, user, secret, onProcessRunnable);
|
||||
createClearOrDeleteDialogAlert(fragment, clear, admin, true, chat, user, false, checkDeleteForAll, onProcessRunnable);
|
||||
} else {
|
||||
if (onProcessRunnable != null) {
|
||||
onProcessRunnable.run(deleteForAll[0]);
|
||||
|
@ -1824,6 +1943,188 @@ public class AlertsCreator {
|
|||
return builder;
|
||||
}
|
||||
|
||||
|
||||
public static BottomSheet.Builder createDatePickerDialog(Context context, long currentDate, final ScheduleDatePickerDelegate datePickerDelegate) {
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ScheduleDatePickerColors datePickerColors = new ScheduleDatePickerColors();
|
||||
BottomSheet.Builder builder = new BottomSheet.Builder(context, false);
|
||||
builder.setApplyBottomPadding(false);
|
||||
|
||||
final NumberPicker dayPicker = new NumberPicker(context);
|
||||
dayPicker.setTextColor(datePickerColors.textColor);
|
||||
dayPicker.setTextOffset(AndroidUtilities.dp(10));
|
||||
dayPicker.setItemCount(5);
|
||||
final NumberPicker hourPicker = new NumberPicker(context) {
|
||||
@Override
|
||||
protected CharSequence getContentDescription(int value) {
|
||||
return LocaleController.formatPluralString("Hours", value);
|
||||
}
|
||||
};
|
||||
hourPicker.setItemCount(5);
|
||||
hourPicker.setTextColor(datePickerColors.textColor);
|
||||
hourPicker.setTextOffset(-AndroidUtilities.dp(10));
|
||||
final NumberPicker minutePicker = new NumberPicker(context) {
|
||||
@Override
|
||||
protected CharSequence getContentDescription(int value) {
|
||||
return LocaleController.formatPluralString("Minutes", value);
|
||||
}
|
||||
};
|
||||
minutePicker.setItemCount(5);
|
||||
minutePicker.setTextColor(datePickerColors.textColor);
|
||||
minutePicker.setTextOffset(-AndroidUtilities.dp(34));
|
||||
|
||||
LinearLayout container = new LinearLayout(context) {
|
||||
|
||||
boolean ignoreLayout = false;
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
ignoreLayout = true;
|
||||
int count;
|
||||
if (AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y) {
|
||||
count = 3;
|
||||
} else {
|
||||
count = 5;
|
||||
}
|
||||
dayPicker.setItemCount(count);
|
||||
hourPicker.setItemCount(count);
|
||||
minutePicker.setItemCount(count);
|
||||
dayPicker.getLayoutParams().height = AndroidUtilities.dp(54) * count;
|
||||
hourPicker.getLayoutParams().height = AndroidUtilities.dp(54) * count;
|
||||
minutePicker.getLayoutParams().height = AndroidUtilities.dp(54) * count;
|
||||
ignoreLayout = false;
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
if (ignoreLayout) {
|
||||
return;
|
||||
}
|
||||
super.requestLayout();
|
||||
}
|
||||
};
|
||||
container.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
FrameLayout titleLayout = new FrameLayout(context);
|
||||
container.addView(titleLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 22, 0, 0, 4));
|
||||
|
||||
TextView titleView = new TextView(context);
|
||||
titleView.setText(LocaleController.getString("ExpireAfter", R.string.ExpireAfter));
|
||||
|
||||
titleView.setTextColor(datePickerColors.textColor);
|
||||
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
titleLayout.addView(titleView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 12, 0, 0));
|
||||
titleView.setOnTouchListener((v, event) -> true);
|
||||
|
||||
LinearLayout linearLayout = new LinearLayout(context);
|
||||
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
linearLayout.setWeightSum(1.0f);
|
||||
container.addView(linearLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(currentTime);
|
||||
int currentYear = calendar.get(Calendar.YEAR);
|
||||
|
||||
TextView buttonTextView = new TextView(context) {
|
||||
@Override
|
||||
public CharSequence getAccessibilityClassName() {
|
||||
return Button.class.getName();
|
||||
}
|
||||
};
|
||||
|
||||
linearLayout.addView(dayPicker, LayoutHelper.createLinear(0, 54 * 5, 0.5f));
|
||||
dayPicker.setMinValue(0);
|
||||
dayPicker.setMaxValue(365);
|
||||
dayPicker.setWrapSelectorWheel(false);
|
||||
dayPicker.setFormatter(value -> {
|
||||
if (value == 0) {
|
||||
return LocaleController.getString("MessageScheduleToday", R.string.MessageScheduleToday);
|
||||
} else {
|
||||
long date = currentTime + (long) value * 86400000L;
|
||||
calendar.setTimeInMillis(date);
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
if (year == currentYear) {
|
||||
return LocaleController.getInstance().formatterScheduleDay.format(date);
|
||||
} else {
|
||||
return LocaleController.getInstance().formatterScheduleYear.format(date);
|
||||
}
|
||||
}
|
||||
});
|
||||
final NumberPicker.OnValueChangeListener onValueChangeListener = (picker, oldVal, newVal) -> {
|
||||
try {
|
||||
container.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
|
||||
} catch (Exception ignore) {
|
||||
|
||||
}
|
||||
checkScheduleDate(null, false, dayPicker, hourPicker, minutePicker);
|
||||
};
|
||||
dayPicker.setOnValueChangedListener(onValueChangeListener);
|
||||
|
||||
hourPicker.setMinValue(0);
|
||||
hourPicker.setMaxValue(23);
|
||||
linearLayout.addView(hourPicker, LayoutHelper.createLinear(0, 54 * 5, 0.2f));
|
||||
hourPicker.setFormatter(value -> String.format("%02d", value));
|
||||
hourPicker.setOnValueChangedListener(onValueChangeListener);
|
||||
|
||||
minutePicker.setMinValue(0);
|
||||
minutePicker.setMaxValue(59);
|
||||
minutePicker.setValue(0);
|
||||
minutePicker.setFormatter(value -> String.format("%02d", value));
|
||||
linearLayout.addView(minutePicker, LayoutHelper.createLinear(0, 54 * 5, 0.3f));
|
||||
minutePicker.setOnValueChangedListener(onValueChangeListener);
|
||||
|
||||
if (currentDate > 0 && currentDate != 0x7FFFFFFE) {
|
||||
currentDate *= 1000;
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
int days = (int) ((currentDate - calendar.getTimeInMillis()) / (24 * 60 * 60 * 1000));
|
||||
calendar.setTimeInMillis(currentDate);
|
||||
if (days >= 0) {
|
||||
minutePicker.setValue(calendar.get(Calendar.MINUTE));
|
||||
hourPicker.setValue(calendar.get(Calendar.HOUR_OF_DAY));
|
||||
dayPicker.setValue(days);
|
||||
}
|
||||
}
|
||||
final boolean[] canceled = {true};
|
||||
|
||||
checkScheduleDate(null, false, dayPicker, hourPicker, minutePicker);
|
||||
|
||||
buttonTextView.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0);
|
||||
buttonTextView.setGravity(Gravity.CENTER);
|
||||
buttonTextView.setTextColor(datePickerColors.buttonTextColor);
|
||||
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor));
|
||||
buttonTextView.setText(LocaleController.getString("SetTimeLimit", R.string.SetTimeLimit));
|
||||
container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16));
|
||||
buttonTextView.setOnClickListener(v -> {
|
||||
canceled[0] = false;
|
||||
boolean setSeconds = checkScheduleDate(null, false, dayPicker, hourPicker, minutePicker);
|
||||
calendar.setTimeInMillis(System.currentTimeMillis() + (long) dayPicker.getValue() * 24 * 3600 * 1000);
|
||||
calendar.set(Calendar.HOUR_OF_DAY, hourPicker.getValue());
|
||||
calendar.set(Calendar.MINUTE, minutePicker.getValue());
|
||||
if (setSeconds) {
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
}
|
||||
datePickerDelegate.didSelectDate(true, (int) (calendar.getTimeInMillis() / 1000));
|
||||
builder.getDismissRunnable().run();
|
||||
});
|
||||
|
||||
builder.setCustomView(container);
|
||||
BottomSheet bottomSheet = builder.show();
|
||||
bottomSheet.setBackgroundColor(datePickerColors.backgroundColor);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static void checkCalendarDate(long minDate, NumberPicker dayPicker, NumberPicker monthPicker, NumberPicker yearPicker) {
|
||||
int day = dayPicker.getValue();
|
||||
int month = monthPicker.getValue();
|
||||
|
@ -2099,13 +2400,25 @@ public class AlertsCreator {
|
|||
|
||||
BottomSheet.Builder builder = new BottomSheet.Builder(context);
|
||||
builder.setTitle(LocaleController.getString("ReportChat", R.string.ReportChat), true);
|
||||
CharSequence[] items = new CharSequence[]{
|
||||
LocaleController.getString("ReportChatSpam", R.string.ReportChatSpam),
|
||||
LocaleController.getString("ReportChatViolence", R.string.ReportChatViolence),
|
||||
LocaleController.getString("ReportChatChild", R.string.ReportChatChild),
|
||||
LocaleController.getString("ReportChatPornography", R.string.ReportChatPornography),
|
||||
LocaleController.getString("ReportChatOther", R.string.ReportChatOther)
|
||||
};
|
||||
CharSequence[] items;
|
||||
if (messageId != 0) {
|
||||
items = new CharSequence[]{
|
||||
LocaleController.getString("ReportChatSpam", R.string.ReportChatSpam),
|
||||
LocaleController.getString("ReportChatViolence", R.string.ReportChatViolence),
|
||||
LocaleController.getString("ReportChatChild", R.string.ReportChatChild),
|
||||
LocaleController.getString("ReportChatPornography", R.string.ReportChatPornography),
|
||||
LocaleController.getString("ReportChatOther", R.string.ReportChatOther)
|
||||
};
|
||||
} else {
|
||||
items = new CharSequence[]{
|
||||
LocaleController.getString("ReportChatSpam", R.string.ReportChatSpam),
|
||||
LocaleController.getString("ReportChatFakeAccount", R.string.ReportChatFakeAccount),
|
||||
LocaleController.getString("ReportChatViolence", R.string.ReportChatViolence),
|
||||
LocaleController.getString("ReportChatChild", R.string.ReportChatChild),
|
||||
LocaleController.getString("ReportChatPornography", R.string.ReportChatPornography),
|
||||
LocaleController.getString("ReportChatOther", R.string.ReportChatOther)
|
||||
};
|
||||
}
|
||||
builder.setItems(items, (dialogInterface, i) -> {
|
||||
if (i == 4) {
|
||||
Bundle args = new Bundle();
|
||||
|
@ -2136,10 +2449,12 @@ public class AlertsCreator {
|
|||
if (i == 0) {
|
||||
request.reason = new TLRPC.TL_inputReportReasonSpam();
|
||||
} else if (i == 1) {
|
||||
request.reason = new TLRPC.TL_inputReportReasonViolence();
|
||||
request.reason = new TLRPC.TL_inputReportReasonFake();
|
||||
} else if (i == 2) {
|
||||
request.reason = new TLRPC.TL_inputReportReasonChildAbuse();
|
||||
request.reason = new TLRPC.TL_inputReportReasonViolence();
|
||||
} else if (i == 3) {
|
||||
request.reason = new TLRPC.TL_inputReportReasonChildAbuse();
|
||||
} else if (i == 4) {
|
||||
request.reason = new TLRPC.TL_inputReportReasonPornography();
|
||||
}
|
||||
req = request;
|
||||
|
|
|
@ -33,18 +33,13 @@ import android.graphics.drawable.Drawable;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
|
@ -52,6 +47,13 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ApplicationLoader;
|
||||
import org.telegram.messenger.BuildConfig;
|
||||
|
@ -162,6 +164,58 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
private int TAG;
|
||||
|
||||
private LaunchActivity parentActivity;
|
||||
int rewindingState;
|
||||
float rewindingProgress = -1;
|
||||
|
||||
int rewindingForwardPressedCount;
|
||||
long lastRewindingTime;
|
||||
long lastUpdateRewindingPlayerTime;
|
||||
|
||||
private final Runnable forwardSeek = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long duration = MediaController.getInstance().getDuration();
|
||||
if (duration == 0 || duration == C.TIME_UNSET) {
|
||||
lastRewindingTime = System.currentTimeMillis();
|
||||
return;
|
||||
}
|
||||
float currentProgress = rewindingProgress;
|
||||
|
||||
long t = System.currentTimeMillis();
|
||||
long dt = t - lastRewindingTime;
|
||||
lastRewindingTime = t;
|
||||
long updateDt = t - lastUpdateRewindingPlayerTime;
|
||||
if (rewindingForwardPressedCount == 1) {
|
||||
dt = dt * 3 - dt;
|
||||
} else if (rewindingForwardPressedCount == 2) {
|
||||
dt = dt * 6 - dt;
|
||||
} else {
|
||||
dt = dt * 12 - dt;
|
||||
}
|
||||
long currentTime = (long) (duration * currentProgress + dt);
|
||||
currentProgress = currentTime / (float) duration;
|
||||
if (currentProgress < 0) {
|
||||
currentProgress = 0;
|
||||
}
|
||||
rewindingProgress = currentProgress;
|
||||
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
|
||||
if (messageObject != null && messageObject.isMusic()) {
|
||||
if (!MediaController.getInstance().isMessagePaused()) {
|
||||
MediaController.getInstance().getPlayingMessageObject().audioProgress = rewindingProgress;
|
||||
}
|
||||
updateProgress(messageObject);
|
||||
}
|
||||
if (rewindingState == 1 && rewindingForwardPressedCount > 0 && MediaController.getInstance().isMessagePaused()) {
|
||||
if (updateDt > 200 || rewindingProgress == 0) {
|
||||
lastUpdateRewindingPlayerTime = t;
|
||||
MediaController.getInstance().seekToProgress(MediaController.getInstance().getPlayingMessageObject(), currentProgress);
|
||||
}
|
||||
if (rewindingForwardPressedCount > 0 && rewindingProgress > 0) {
|
||||
AndroidUtilities.runOnUIThread(forwardSeek, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public AudioPlayerAlert(final Context context) {
|
||||
super(context, true);
|
||||
|
@ -524,12 +578,43 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
textView.setSingleLine(true);
|
||||
textView.setPadding(AndroidUtilities.dp(6), 0, AndroidUtilities.dp(6), AndroidUtilities.dp(1));
|
||||
textView.setBackground(Theme.createRadSelectorDrawable(Theme.getColor(Theme.key_listSelector), AndroidUtilities.dp(4), AndroidUtilities.dp(4)));
|
||||
|
||||
textView.setOnClickListener(view -> {
|
||||
int dialogsCount = MessagesController.getInstance(currentAccount).getTotalDialogsCount();
|
||||
if (dialogsCount <= 10) {
|
||||
return;
|
||||
}
|
||||
String query = (String) textView.getText();
|
||||
if (parentActivity.getActionBarLayout().getLastFragment() instanceof DialogsActivity) {
|
||||
DialogsActivity dialogsActivity = (DialogsActivity) parentActivity.getActionBarLayout().getLastFragment();
|
||||
if (!dialogsActivity.onlyDialogsAdapter()) {
|
||||
dialogsActivity.setShowSearch(query, 4);
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
}
|
||||
DialogsActivity fragment = new DialogsActivity(null);
|
||||
fragment.setSearchString(query);
|
||||
fragment.setInitialSearchType(4);
|
||||
parentActivity.presentFragment(fragment, false, false);
|
||||
dismiss();
|
||||
});
|
||||
return textView;
|
||||
}
|
||||
};
|
||||
playerLayout.addView(authorTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 20, 47, 72, 0));
|
||||
playerLayout.addView(authorTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 14, 47, 72, 0));
|
||||
|
||||
seekBarView = new SeekBarView(context);
|
||||
seekBarView = new SeekBarView(context) {
|
||||
@Override
|
||||
boolean onTouch(MotionEvent ev) {
|
||||
if (rewindingState != 0) {
|
||||
return false;
|
||||
}
|
||||
return super.onTouch(ev);
|
||||
}
|
||||
};
|
||||
seekBarView.setDelegate(new SeekBarView.SeekBarViewDelegate() {
|
||||
@Override
|
||||
public void onSeekBarDrag(boolean stop, float progress) {
|
||||
|
@ -659,8 +744,135 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
});
|
||||
|
||||
final int iconColor = Theme.getColor(Theme.key_player_button);
|
||||
float touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||
|
||||
buttons[1] = prevButton = new RLottieImageView(context);
|
||||
buttons[1] = prevButton = new RLottieImageView(context) {
|
||||
float startX;
|
||||
float startY;
|
||||
|
||||
int pressedCount = 0;
|
||||
|
||||
long lastTime;
|
||||
long lastUpdateTime;
|
||||
|
||||
private final Runnable pressedRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pressedCount++;
|
||||
if (pressedCount == 1) {
|
||||
rewindingState = -1;
|
||||
rewindingProgress = MediaController.getInstance().getPlayingMessageObject().audioProgress;
|
||||
lastTime = System.currentTimeMillis();
|
||||
AndroidUtilities.runOnUIThread(this, 2000);
|
||||
AndroidUtilities.runOnUIThread(backSeek);
|
||||
} else if (pressedCount == 2) {
|
||||
AndroidUtilities.runOnUIThread(this, 2000);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable backSeek = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long duration = MediaController.getInstance().getDuration();
|
||||
if (duration == 0 || duration == C.TIME_UNSET) {
|
||||
lastTime = System.currentTimeMillis();
|
||||
return;
|
||||
}
|
||||
float currentProgress = rewindingProgress;
|
||||
|
||||
long t = System.currentTimeMillis();
|
||||
long dt = t - lastTime;
|
||||
lastTime = t;
|
||||
long updateDt = t - lastUpdateTime;
|
||||
if (pressedCount == 1) {
|
||||
dt *= 3;
|
||||
} else if (pressedCount == 2) {
|
||||
dt *= 6;
|
||||
} else {
|
||||
dt *= 12;
|
||||
}
|
||||
long currentTime = (long) (duration * currentProgress - dt);
|
||||
currentProgress = currentTime / (float) duration;
|
||||
if (currentProgress < 0) {
|
||||
currentProgress = 0;
|
||||
}
|
||||
rewindingProgress = currentProgress;
|
||||
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
|
||||
if (messageObject != null && messageObject.isMusic()) {
|
||||
updateProgress(messageObject);
|
||||
}
|
||||
if (rewindingState == -1 && pressedCount > 0) {
|
||||
if (updateDt > 200 || rewindingProgress == 0) {
|
||||
lastUpdateTime = t;
|
||||
if (rewindingProgress == 0) {
|
||||
MediaController.getInstance().seekToProgress(MediaController.getInstance().getPlayingMessageObject(), 0);
|
||||
MediaController.getInstance().pauseByRewind();
|
||||
} else {
|
||||
MediaController.getInstance().seekToProgress(MediaController.getInstance().getPlayingMessageObject(), currentProgress);
|
||||
}
|
||||
}
|
||||
if (pressedCount > 0 && rewindingProgress > 0) {
|
||||
AndroidUtilities.runOnUIThread(backSeek, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
long startTime;
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (seekBarView.isDragging() || rewindingState == 1) {
|
||||
return false;
|
||||
}
|
||||
float x = event.getRawX();
|
||||
float y = event.getRawY();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
startX = x;
|
||||
startY = y;
|
||||
startTime = System.currentTimeMillis();
|
||||
rewindingState = 0;
|
||||
AndroidUtilities.runOnUIThread(pressedRunnable, 300);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && getBackground() != null) {
|
||||
getBackground().setHotspot(startX, startY);
|
||||
}
|
||||
setPressed(true);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float dx = x - startX;
|
||||
float dy = y - startY;
|
||||
|
||||
if ((dx * dx + dy * dy) > touchSlop * touchSlop && rewindingState == 0) {
|
||||
AndroidUtilities.cancelRunOnUIThread(pressedRunnable);
|
||||
setPressed(false);
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
AndroidUtilities.cancelRunOnUIThread(pressedRunnable);
|
||||
AndroidUtilities.cancelRunOnUIThread(backSeek);
|
||||
if (rewindingState == 0 && event.getAction() == MotionEvent.ACTION_UP && (System.currentTimeMillis() - startTime < 300)) {
|
||||
MediaController.getInstance().playPreviousMessage();
|
||||
prevButton.setProgress(0f);
|
||||
prevButton.playAnimation();
|
||||
}
|
||||
if (pressedCount > 0) {
|
||||
lastUpdateTime = 0;
|
||||
backSeek.run();
|
||||
MediaController.getInstance().resumeByRewind();
|
||||
}
|
||||
rewindingProgress = -1;
|
||||
setPressed(false);
|
||||
rewindingState = 0;
|
||||
pressedCount = 0;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
prevButton.setScaleType(ImageView.ScaleType.CENTER);
|
||||
prevButton.setAnimation(R.raw.player_prev, 20, 20);
|
||||
prevButton.setLayerColor("Triangle 3.**", iconColor);
|
||||
|
@ -670,11 +882,6 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
prevButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 1, AndroidUtilities.dp(22)));
|
||||
}
|
||||
bottomView.addView(prevButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
|
||||
prevButton.setOnClickListener(v -> {
|
||||
MediaController.getInstance().playPreviousMessage();
|
||||
prevButton.setProgress(0f);
|
||||
prevButton.playAnimation();
|
||||
});
|
||||
prevButton.setContentDescription(LocaleController.getString("AccDescrPrevious", R.string.AccDescrPrevious));
|
||||
|
||||
buttons[2] = playButton = new ImageView(context);
|
||||
|
@ -697,7 +904,92 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
}
|
||||
});
|
||||
|
||||
buttons[3] = nextButton = new RLottieImageView(context);
|
||||
buttons[3] = nextButton = new RLottieImageView(context) {
|
||||
|
||||
float startX;
|
||||
float startY;
|
||||
boolean pressed;
|
||||
|
||||
private final Runnable pressedRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (MediaController.getInstance().getPlayingMessageObject() == null) {
|
||||
return;
|
||||
}
|
||||
rewindingForwardPressedCount++;
|
||||
if (rewindingForwardPressedCount == 1) {
|
||||
pressed = true;
|
||||
rewindingState = 1;
|
||||
if (MediaController.getInstance().isMessagePaused()) {
|
||||
startForwardRewindingSeek();
|
||||
} else if (rewindingState == 1) {
|
||||
AndroidUtilities.cancelRunOnUIThread(forwardSeek);
|
||||
lastUpdateRewindingPlayerTime = 0;
|
||||
}
|
||||
MediaController.getInstance().setPlaybackSpeed(true, 4);
|
||||
AndroidUtilities.runOnUIThread(this, 2000);
|
||||
} else if (rewindingForwardPressedCount == 2) {
|
||||
MediaController.getInstance().setPlaybackSpeed(true, 7);
|
||||
AndroidUtilities.runOnUIThread(this, 2000);
|
||||
} else {
|
||||
MediaController.getInstance().setPlaybackSpeed(true, 13);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (seekBarView.isDragging() || rewindingState == -1) {
|
||||
return false;
|
||||
}
|
||||
float x = event.getRawX();
|
||||
float y = event.getRawY();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
pressed = false;
|
||||
startX = x;
|
||||
startY = y;
|
||||
AndroidUtilities.runOnUIThread(pressedRunnable, 300);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && getBackground() != null) {
|
||||
getBackground().setHotspot(startX, startY);
|
||||
}
|
||||
setPressed(true);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float dx = x - startX;
|
||||
float dy = y - startY;
|
||||
|
||||
if ((dx * dx + dy * dy) > touchSlop * touchSlop && !pressed) {
|
||||
AndroidUtilities.cancelRunOnUIThread(pressedRunnable);
|
||||
setPressed(false);
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (!pressed && event.getAction() == MotionEvent.ACTION_UP && isPressed()) {
|
||||
MediaController.getInstance().playNextMessage();
|
||||
nextButton.setProgress(0f);
|
||||
nextButton.playAnimation();
|
||||
}
|
||||
AndroidUtilities.cancelRunOnUIThread(pressedRunnable);
|
||||
if (rewindingForwardPressedCount > 0) {
|
||||
MediaController.getInstance().setPlaybackSpeed(true, 1f);
|
||||
if (MediaController.getInstance().isMessagePaused()) {
|
||||
lastUpdateRewindingPlayerTime = 0;
|
||||
forwardSeek.run();
|
||||
}
|
||||
}
|
||||
rewindingState = 0;
|
||||
setPressed(false);
|
||||
rewindingForwardPressedCount = 0;
|
||||
rewindingProgress = -1;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
nextButton.setScaleType(ImageView.ScaleType.CENTER);
|
||||
nextButton.setAnimation(R.raw.player_prev, 20, 20);
|
||||
nextButton.setLayerColor("Triangle 3.**", iconColor);
|
||||
|
@ -708,11 +1000,6 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
nextButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 1, AndroidUtilities.dp(22)));
|
||||
}
|
||||
bottomView.addView(nextButton, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
|
||||
nextButton.setOnClickListener(v -> {
|
||||
MediaController.getInstance().playNextMessage();
|
||||
nextButton.setProgress(0f);
|
||||
nextButton.playAnimation();
|
||||
});
|
||||
nextButton.setContentDescription(LocaleController.getString("Next", R.string.Next));
|
||||
|
||||
buttons[4] = optionsButton = new ActionBarMenuItem(context, null, 0, iconColor);
|
||||
|
@ -888,6 +1175,15 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
updateEmptyView();
|
||||
}
|
||||
|
||||
private void startForwardRewindingSeek() {
|
||||
if (rewindingState == 1) {
|
||||
lastRewindingTime = System.currentTimeMillis();
|
||||
rewindingProgress = MediaController.getInstance().getPlayingMessageObject().audioProgress;
|
||||
AndroidUtilities.cancelRunOnUIThread(forwardSeek);
|
||||
AndroidUtilities.runOnUIThread(forwardSeek);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEmptyViewPosition() {
|
||||
if (emptyView.getVisibility() != View.VISIBLE) {
|
||||
return;
|
||||
|
@ -1201,6 +1497,18 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
}
|
||||
}
|
||||
}
|
||||
if (id == NotificationCenter.messagePlayingPlayStateChanged) {
|
||||
if (MediaController.getInstance().getPlayingMessageObject() != null) {
|
||||
if (MediaController.getInstance().isMessagePaused()) {
|
||||
startForwardRewindingSeek();
|
||||
} else if (rewindingState == 1 && rewindingProgress != -1f) {
|
||||
AndroidUtilities.cancelRunOnUIThread(forwardSeek);
|
||||
lastUpdateRewindingPlayerTime = 0;
|
||||
forwardSeek.run();
|
||||
rewindingProgress = -1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (id == NotificationCenter.messagePlayingDidStart) {
|
||||
MessageObject messageObject = (MessageObject) args[0];
|
||||
if (messageObject.eventId != 0) {
|
||||
|
@ -1433,7 +1741,12 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
if (seekBarView.isDragging()) {
|
||||
newTime = (int) (messageObject.getDuration() * seekBarView.getProgress());
|
||||
} else {
|
||||
seekBarView.setProgress(messageObject.audioProgress, animated);
|
||||
boolean updateRewinding = rewindingProgress >= 0 && (rewindingState == -1 || (rewindingState == 1 && MediaController.getInstance().isMessagePaused()));
|
||||
if (updateRewinding) {
|
||||
seekBarView.setProgress(rewindingProgress, animated);
|
||||
} else {
|
||||
seekBarView.setProgress(messageObject.audioProgress, animated);
|
||||
}
|
||||
|
||||
float bufferedProgress;
|
||||
if (currentAudioFinishedLoading) {
|
||||
|
@ -1450,7 +1763,12 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
if (bufferedProgress != -1) {
|
||||
seekBarView.setBufferedProgress(bufferedProgress);
|
||||
}
|
||||
newTime = messageObject.audioProgressSec;
|
||||
if (updateRewinding) {
|
||||
newTime = (int) (messageObject.getDuration() * seekBarView.getProgress());
|
||||
messageObject.audioProgressSec = newTime;
|
||||
} else {
|
||||
newTime = messageObject.audioProgressSec;
|
||||
}
|
||||
}
|
||||
if (lastTime != newTime) {
|
||||
lastTime = newTime;
|
||||
|
@ -1999,6 +2317,8 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
private int activeIndex;
|
||||
private AnimatorSet animatorSet;
|
||||
private LinearGradient gradientShader;
|
||||
private int stableOffest = -1;
|
||||
private final RectF rectF = new RectF();
|
||||
|
||||
public ClippingTextViewSwitcher(@NonNull Context context) {
|
||||
super(context);
|
||||
|
@ -2028,7 +2348,27 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
final int index = child == textViews[0] ? 0 : 1;
|
||||
final boolean result;
|
||||
if (clipProgress[index] > 0f) {
|
||||
boolean hasStableRect = false;
|
||||
if (stableOffest > 0 && textViews[activeIndex].getAlpha() != 1f && textViews[activeIndex].getLayout() != null) {
|
||||
float x1 = textViews[activeIndex].getLayout().getPrimaryHorizontal(0);
|
||||
float x2 = textViews[activeIndex].getLayout().getPrimaryHorizontal(stableOffest);
|
||||
hasStableRect = true;
|
||||
if (x1 == x2) {
|
||||
hasStableRect = false;
|
||||
} else if (x2 > x1) {
|
||||
rectF.set(x1, 0, x2, getMeasuredHeight());
|
||||
} else {
|
||||
rectF.set(x2, 0, x1, getMeasuredHeight());
|
||||
}
|
||||
|
||||
if (hasStableRect && index == activeIndex) {
|
||||
canvas.save();
|
||||
canvas.clipRect(rectF);
|
||||
textViews[0].draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
if (clipProgress[index] > 0f || hasStableRect) {
|
||||
final int width = child.getWidth();
|
||||
final int height = child.getHeight();
|
||||
final int saveCount = canvas.saveLayer(0, 0, width, height, null, Canvas.ALL_SAVE_FLAG);
|
||||
|
@ -2041,6 +2381,9 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
if (width > gradientEnd) {
|
||||
canvas.drawRect(gradientEnd, 0, width, height, erasePaint);
|
||||
}
|
||||
if (hasStableRect) {
|
||||
canvas.drawRect(rectF, erasePaint);
|
||||
}
|
||||
canvas.restoreToCount(saveCount);
|
||||
} else {
|
||||
result = super.drawChild(canvas, child, drawingTime);
|
||||
|
@ -2049,15 +2392,31 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
|
|||
}
|
||||
|
||||
public void setText(CharSequence text) {
|
||||
setText(text, true);
|
||||
}
|
||||
|
||||
public void setText(CharSequence text, boolean animated) {
|
||||
final CharSequence currentText = textViews[activeIndex].getText();
|
||||
|
||||
if (TextUtils.isEmpty(currentText)) {
|
||||
if (TextUtils.isEmpty(currentText) || !animated) {
|
||||
textViews[activeIndex].setText(text);
|
||||
return;
|
||||
} else if (TextUtils.equals(text, currentText)) {
|
||||
return;
|
||||
}
|
||||
|
||||
stableOffest = 0;
|
||||
int n = Math.min(text.length(), currentText.length());
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (text.charAt(i) != currentText.charAt(i)) {
|
||||
break;
|
||||
}
|
||||
stableOffest++;
|
||||
}
|
||||
if (stableOffest <= 3) {
|
||||
stableOffest = -1;
|
||||
}
|
||||
|
||||
final int index = activeIndex == 0 ? 1 : 0;
|
||||
final int prevIndex = activeIndex;
|
||||
activeIndex = index;
|
||||
|
|
|
@ -242,6 +242,7 @@ public class AvatarsImageView extends FrameLayout {
|
|||
protected void onDraw(Canvas canvas) {
|
||||
wasDraw = true;
|
||||
|
||||
int size = AndroidUtilities.dp(currentStyle == 4 ? 32 : 24);
|
||||
int toAdd = AndroidUtilities.dp(currentStyle == 4 ? 24 : 20);
|
||||
int drawCount = 0;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
@ -249,7 +250,7 @@ public class AvatarsImageView extends FrameLayout {
|
|||
drawCount++;
|
||||
}
|
||||
}
|
||||
int ax = centered ? (getMeasuredWidth() - drawCount * toAdd - AndroidUtilities.dp(currentStyle == 4 ? 8 : 4)) / 2 : AndroidUtilities.dp(10);
|
||||
int ax = centered ? (getMeasuredWidth() - drawCount * toAdd - AndroidUtilities.dp(currentStyle == 4 ? 8 : 4)) / 2 : (currentStyle == 0 ? 0 : AndroidUtilities.dp(10));
|
||||
boolean isMuted = VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().isMicMute();
|
||||
if (currentStyle == 4) {
|
||||
paint.setColor(Theme.getColor(Theme.key_inappPlayerBackground));
|
||||
|
@ -263,7 +264,7 @@ public class AvatarsImageView extends FrameLayout {
|
|||
animateToDrawCount++;
|
||||
}
|
||||
}
|
||||
boolean useAlphaLayer = currentStyle == 3 || currentStyle == 4 || currentStyle == 5;
|
||||
boolean useAlphaLayer = currentStyle == 0 || currentStyle == 1 || currentStyle == 3 || currentStyle == 4 || currentStyle == 5;
|
||||
if (useAlphaLayer) {
|
||||
canvas.saveLayerAlpha(0, 0, getMeasuredWidth(), getMeasuredHeight(), 255, Canvas.ALL_SAVE_FLAG);
|
||||
}
|
||||
|
@ -289,7 +290,11 @@ public class AvatarsImageView extends FrameLayout {
|
|||
imageReceiver.setImageX(ax + toAdd * a);
|
||||
}
|
||||
|
||||
imageReceiver.setImageY(AndroidUtilities.dp(currentStyle == 4 ? 8 : 6));
|
||||
if (currentStyle == 0) {
|
||||
imageReceiver.setImageY((getMeasuredHeight() - size) / 2f);
|
||||
} else {
|
||||
imageReceiver.setImageY(AndroidUtilities.dp(currentStyle == 4 ? 8 : 6));
|
||||
}
|
||||
|
||||
boolean needRestore = false;
|
||||
float alpha = 1f;
|
||||
|
@ -319,7 +324,7 @@ public class AvatarsImageView extends FrameLayout {
|
|||
|
||||
float avatarScale = 1f;
|
||||
if (a != states.length - 1) {
|
||||
if (currentStyle == 3 || currentStyle == 5) {
|
||||
if (currentStyle == 1 || currentStyle == 3 || currentStyle == 5) {
|
||||
canvas.drawCircle(imageReceiver.getCenterX(), imageReceiver.getCenterY(), AndroidUtilities.dp(13), xRefP);
|
||||
if (states[a].wavesDrawable == null) {
|
||||
if (currentStyle == 5) {
|
||||
|
@ -331,7 +336,7 @@ public class AvatarsImageView extends FrameLayout {
|
|||
if (currentStyle == 5) {
|
||||
states[a].wavesDrawable.setColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_speakingText), (int) (255 * 0.3f * alpha)));
|
||||
}
|
||||
if (states[a].participant.amplitude > 0) {
|
||||
if (states[a].participant != null && states[a].participant.amplitude > 0) {
|
||||
states[a].wavesDrawable.setShowWaves(true, this);
|
||||
float amplitude = states[a].participant.amplitude * 15f;
|
||||
states[a].wavesDrawable.setAmplitude(amplitude);
|
||||
|
@ -368,13 +373,17 @@ public class AvatarsImageView extends FrameLayout {
|
|||
states[a].wavesDrawable.draw(canvas, imageReceiver.getCenterX(), imageReceiver.getCenterY(), this);
|
||||
avatarScale = states[a].wavesDrawable.getAvatarScale();
|
||||
} else {
|
||||
int paintAlpha = paint.getAlpha();
|
||||
if (alpha != 1f) {
|
||||
paint.setAlpha((int) (paintAlpha * alpha));
|
||||
}
|
||||
canvas.drawCircle(imageReceiver.getCenterX(), imageReceiver.getCenterY(), AndroidUtilities.dp(currentStyle == 4 ? 17 : 13), paint);
|
||||
if (alpha != 1f) {
|
||||
paint.setAlpha(paintAlpha);
|
||||
if (useAlphaLayer) {
|
||||
canvas.drawCircle(imageReceiver.getCenterX(), imageReceiver.getCenterY(), AndroidUtilities.dp(currentStyle == 4 ? 17 : 13), xRefP);
|
||||
} else {
|
||||
int paintAlpha = paint.getAlpha();
|
||||
if (alpha != 1f) {
|
||||
paint.setAlpha((int) (paintAlpha * alpha));
|
||||
}
|
||||
canvas.drawCircle(imageReceiver.getCenterX(), imageReceiver.getCenterY(), AndroidUtilities.dp(currentStyle == 4 ? 17 : 13), paint);
|
||||
if (alpha != 1f) {
|
||||
paint.setAlpha(paintAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,15 @@ import android.animation.ObjectAnimator;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Property;
|
||||
import android.util.TypedValue;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.Gravity;
|
||||
|
@ -32,6 +34,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.core.util.Consumer;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.dynamicanimation.animation.DynamicAnimation;
|
||||
import androidx.dynamicanimation.animation.FloatPropertyCompat;
|
||||
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||
import androidx.dynamicanimation.animation.SpringForce;
|
||||
|
||||
|
@ -104,7 +107,7 @@ public final class Bulletin {
|
|||
|
||||
private boolean showing;
|
||||
private boolean canHide;
|
||||
private int currentBottomOffset;
|
||||
public int currentBottomOffset;
|
||||
private Delegate currentDelegate;
|
||||
private Layout.Transition layoutTransition;
|
||||
|
||||
|
@ -128,6 +131,10 @@ public final class Bulletin {
|
|||
this.duration = duration;
|
||||
}
|
||||
|
||||
public static Bulletin getVisibleBulletin() {
|
||||
return visibleBulletin;
|
||||
}
|
||||
|
||||
public Bulletin show() {
|
||||
if (!showing) {
|
||||
showing = true;
|
||||
|
@ -154,14 +161,12 @@ public final class Bulletin {
|
|||
currentDelegate.onShow(Bulletin.this);
|
||||
}
|
||||
if (isTransitionsEnabled()) {
|
||||
if (currentBottomOffset != 0) {
|
||||
ViewCompat.setClipBounds(parentLayout, new Rect(left, top - currentBottomOffset, right, bottom - currentBottomOffset));
|
||||
} else {
|
||||
ViewCompat.setClipBounds(parentLayout, null);
|
||||
}
|
||||
ensureLayoutTransitionCreated();
|
||||
layout.transitionRunning = true;
|
||||
layout.delegate = currentDelegate;
|
||||
layout.invalidate();
|
||||
layoutTransition.animateEnter(layout, layout::onEnterTransitionStart, () -> {
|
||||
ViewCompat.setClipBounds(parentLayout, null);
|
||||
layout.transitionRunning = false;
|
||||
layout.onEnterTransitionEnd();
|
||||
setCanHide(true);
|
||||
}, offset -> {
|
||||
|
@ -173,7 +178,7 @@ public final class Bulletin {
|
|||
if (currentDelegate != null) {
|
||||
currentDelegate.onOffsetChange(layout.getHeight() - currentBottomOffset);
|
||||
}
|
||||
layout.setTranslationY(-currentBottomOffset);
|
||||
updatePosition();
|
||||
layout.onEnterTransitionStart();
|
||||
layout.onEnterTransitionEnd();
|
||||
setCanHide(true);
|
||||
|
@ -233,18 +238,16 @@ public final class Bulletin {
|
|||
if (ViewCompat.isLaidOut(layout)) {
|
||||
layout.removeCallbacks(hideRunnable);
|
||||
if (animated) {
|
||||
if (bottomOffset != 0) {
|
||||
ViewCompat.setClipBounds(parentLayout, new Rect(layout.getLeft(), layout.getTop() - bottomOffset, layout.getRight(), layout.getBottom() - bottomOffset));
|
||||
} else {
|
||||
ViewCompat.setClipBounds(parentLayout, null);
|
||||
}
|
||||
layout.transitionRunning = true;
|
||||
layout.delegate = currentDelegate;
|
||||
layout.invalidate();
|
||||
ensureLayoutTransitionCreated();
|
||||
layoutTransition.animateExit(layout, layout::onExitTransitionStart, () -> {
|
||||
if (currentDelegate != null) {
|
||||
currentDelegate.onOffsetChange(0);
|
||||
currentDelegate.onHide(this);
|
||||
}
|
||||
ViewCompat.setClipBounds(parentLayout, null);
|
||||
layout.transitionRunning = false;
|
||||
layout.onExitTransitionEnd();
|
||||
layout.onHide();
|
||||
containerLayout.removeView(parentLayout);
|
||||
|
@ -284,6 +287,10 @@ public final class Bulletin {
|
|||
return MessagesController.getGlobalMainSettings().getBoolean("view_animations", true) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
|
||||
}
|
||||
|
||||
public void updatePosition() {
|
||||
layout.updatePosition();
|
||||
}
|
||||
|
||||
@Retention(SOURCE)
|
||||
@IntDef(value = {ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT})
|
||||
private @interface WidthDef {
|
||||
|
@ -461,6 +468,9 @@ public final class Bulletin {
|
|||
public abstract static class Layout extends FrameLayout {
|
||||
|
||||
private final List<Callback> callbacks = new ArrayList<>();
|
||||
public boolean transitionRunning;
|
||||
Delegate delegate;
|
||||
public float inOutOffset;
|
||||
|
||||
protected Bulletin bulletin;
|
||||
|
||||
|
@ -473,13 +483,42 @@ public final class Bulletin {
|
|||
this(context, Theme.getColor(Theme.key_undo_background));
|
||||
}
|
||||
|
||||
Drawable background;
|
||||
|
||||
public Layout(@NonNull Context context, @ColorInt int backgroundColor) {
|
||||
super(context);
|
||||
setMinimumHeight(AndroidUtilities.dp(48));
|
||||
setBackground(new InsetDrawable(Theme.createRoundRectDrawable(AndroidUtilities.dp(6), backgroundColor), AndroidUtilities.dp(8)));
|
||||
background = Theme.createRoundRectDrawable(AndroidUtilities.dp(6), backgroundColor);
|
||||
updateSize();
|
||||
setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8));
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
public final static FloatPropertyCompat<Layout> IN_OUT_OFFSET_Y = new FloatPropertyCompat<Layout>("offsetY") {
|
||||
@Override
|
||||
public float getValue(Layout object) {
|
||||
return object.inOutOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Layout object, float value) {
|
||||
object.setInOutOffset(value);
|
||||
}
|
||||
};
|
||||
|
||||
public final static Property<Layout, Float> IN_OUT_OFFSET_Y2 = new AnimationProperties.FloatProperty<Layout>("offsetY") {
|
||||
|
||||
@Override
|
||||
public Float get(Layout layout) {
|
||||
return layout.inOutOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Layout object, float value) {
|
||||
object.setInOutOffset(value);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
@ -602,6 +641,14 @@ public final class Bulletin {
|
|||
callbacks.remove(callback);
|
||||
}
|
||||
|
||||
public void updatePosition() {
|
||||
float tranlsation = 0;
|
||||
if (delegate != null) {
|
||||
tranlsation += delegate.getBottomOffset() ;
|
||||
}
|
||||
setTranslationY(-tranlsation + inOutOffset);
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
|
||||
void onAttach(@NonNull Layout layout, @NonNull Bulletin bulletin);
|
||||
|
@ -637,7 +684,11 @@ public final class Bulletin {
|
|||
|
||||
@Override
|
||||
public void animateEnter(@NonNull Layout layout, @Nullable Runnable startAction, @Nullable Runnable endAction, @Nullable Consumer<Float> onUpdate, int bottomOffset) {
|
||||
final ObjectAnimator animator = ObjectAnimator.ofFloat(layout, View.TRANSLATION_Y, layout.getHeight(), -bottomOffset);
|
||||
layout.setInOutOffset(layout.getMeasuredHeight());
|
||||
if (onUpdate != null) {
|
||||
onUpdate.accept(layout.getTranslationY());
|
||||
}
|
||||
final ObjectAnimator animator = ObjectAnimator.ofFloat(layout, IN_OUT_OFFSET_Y2, 0);
|
||||
animator.setDuration(225);
|
||||
animator.setInterpolator(Easings.easeOutQuad);
|
||||
if (startAction != null || endAction != null) {
|
||||
|
@ -658,14 +709,14 @@ public final class Bulletin {
|
|||
});
|
||||
}
|
||||
if (onUpdate != null) {
|
||||
animator.addUpdateListener(a -> onUpdate.accept((Float) a.getAnimatedValue()));
|
||||
animator.addUpdateListener(a -> onUpdate.accept(layout.getTranslationY()));
|
||||
}
|
||||
animator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animateExit(@NonNull Layout layout, @Nullable Runnable startAction, @Nullable Runnable endAction, @Nullable Consumer<Float> onUpdate, int bottomOffset) {
|
||||
final ObjectAnimator animator = ObjectAnimator.ofFloat(layout, View.TRANSLATION_Y, layout.getTranslationY(), layout.getHeight());
|
||||
final ObjectAnimator animator = ObjectAnimator.ofFloat(layout, IN_OUT_OFFSET_Y2, layout.getHeight());
|
||||
animator.setDuration(175);
|
||||
animator.setInterpolator(Easings.easeInQuad);
|
||||
if (startAction != null || endAction != null) {
|
||||
|
@ -686,7 +737,7 @@ public final class Bulletin {
|
|||
});
|
||||
}
|
||||
if (onUpdate != null) {
|
||||
animator.addUpdateListener(a -> onUpdate.accept((Float) a.getAnimatedValue()));
|
||||
animator.addUpdateListener(a -> onUpdate.accept(layout.getTranslationY()));
|
||||
}
|
||||
animator.start();
|
||||
}
|
||||
|
@ -699,23 +750,23 @@ public final class Bulletin {
|
|||
|
||||
@Override
|
||||
public void animateEnter(@NonNull Layout layout, @Nullable Runnable startAction, @Nullable Runnable endAction, @Nullable Consumer<Float> onUpdate, int bottomOffset) {
|
||||
final int translationY = layout.getHeight() - bottomOffset;
|
||||
layout.setTranslationY(translationY);
|
||||
layout.setInOutOffset(layout.getMeasuredHeight());
|
||||
if (onUpdate != null) {
|
||||
onUpdate.accept((float) translationY);
|
||||
onUpdate.accept(layout.getTranslationY());
|
||||
}
|
||||
final SpringAnimation springAnimation = new SpringAnimation(layout, SpringAnimation.TRANSLATION_Y, -bottomOffset);
|
||||
final SpringAnimation springAnimation = new SpringAnimation(layout, IN_OUT_OFFSET_Y, 0);
|
||||
springAnimation.getSpring().setDampingRatio(DAMPING_RATIO);
|
||||
springAnimation.getSpring().setStiffness(STIFFNESS);
|
||||
if (endAction != null) {
|
||||
springAnimation.addEndListener((animation, canceled, value, velocity) -> {
|
||||
layout.setInOutOffset(0);
|
||||
if (!canceled) {
|
||||
endAction.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (onUpdate != null) {
|
||||
springAnimation.addUpdateListener((animation, value, velocity) -> onUpdate.accept(value));
|
||||
springAnimation.addUpdateListener((animation, value, velocity) -> onUpdate.accept(layout.getTranslationY()));
|
||||
}
|
||||
springAnimation.start();
|
||||
if (startAction != null) {
|
||||
|
@ -725,7 +776,7 @@ public final class Bulletin {
|
|||
|
||||
@Override
|
||||
public void animateExit(@NonNull Layout layout, @Nullable Runnable startAction, @Nullable Runnable endAction, @Nullable Consumer<Float> onUpdate,int bottomOffset) {
|
||||
final SpringAnimation springAnimation = new SpringAnimation(layout, SpringAnimation.TRANSLATION_Y, layout.getHeight() - bottomOffset);
|
||||
final SpringAnimation springAnimation = new SpringAnimation(layout, IN_OUT_OFFSET_Y, layout.getHeight());
|
||||
springAnimation.getSpring().setDampingRatio(DAMPING_RATIO);
|
||||
springAnimation.getSpring().setStiffness(STIFFNESS);
|
||||
if (endAction != null) {
|
||||
|
@ -736,7 +787,7 @@ public final class Bulletin {
|
|||
});
|
||||
}
|
||||
if (onUpdate != null) {
|
||||
springAnimation.addUpdateListener((animation, value, velocity) -> onUpdate.accept(value));
|
||||
springAnimation.addUpdateListener((animation, value, velocity) -> onUpdate.accept(layout.getTranslationY()));
|
||||
}
|
||||
springAnimation.start();
|
||||
if (startAction != null) {
|
||||
|
@ -744,6 +795,30 @@ public final class Bulletin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setInOutOffset(float offset) {
|
||||
inOutOffset = offset;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
background.setBounds(AndroidUtilities.dp(8), AndroidUtilities.dp(8), getMeasuredWidth() - AndroidUtilities.dp(8), getMeasuredHeight() - AndroidUtilities.dp(8));
|
||||
if (transitionRunning && delegate != null) {
|
||||
int clipBottom = ((View)getParent()).getMeasuredHeight() - delegate.getBottomOffset();
|
||||
int viewBottom = (int) (getY() + getMeasuredHeight());
|
||||
canvas.save();
|
||||
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight() - (viewBottom - clipBottom));
|
||||
background.draw(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.restore();
|
||||
invalidate();
|
||||
} else {
|
||||
background.draw(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
|
@ -25,6 +26,20 @@ public final class BulletinFactory {
|
|||
return fragment != null && fragment.getParentActivity() != null && fragment.getLayoutContainer() != null;
|
||||
}
|
||||
|
||||
public Bulletin createMembersNotifyInfo(boolean on) {
|
||||
if (on) {
|
||||
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext());
|
||||
layout.setAnimation(R.raw.silent_unmute, 36, 36, "NULL BODY", "BODY", "Waves R", "Waves L", "Bottom");
|
||||
layout.textView.setText(LocaleController.getString("ChannelNotifyMembersInfoOn", R.string.ChannelNotifyMembersInfoOn));
|
||||
return create(layout, Bulletin.DURATION_SHORT);
|
||||
} else {
|
||||
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext());
|
||||
layout.setAnimation(R.raw.silent_mute, 36, 36, "NULL BODY", "BODY", "Pieces", "Line Cross", "Bottom");
|
||||
layout.textView.setText(LocaleController.getString("ChannelNotifyMembersInfoOff", R.string.ChannelNotifyMembersInfoOff));
|
||||
return create(layout, Bulletin.DURATION_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
public enum FileType {
|
||||
|
||||
PHOTO("PhotoSavedHint", R.string.PhotoSavedHint, Icon.SAVED_TO_GALLERY),
|
||||
|
@ -289,6 +304,11 @@ public final class BulletinFactory {
|
|||
return of(fragment).createCopyLinkBulletin();
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
public static Bulletin createCopyLinkBulletin(FrameLayout containerView) {
|
||||
return of(containerView).createCopyLinkBulletin();
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
public static Bulletin createPinMessageBulletin(BaseFragment fragment) {
|
||||
return createPinMessageBulletin(fragment, true, null, null);
|
||||
|
|
|
@ -218,6 +218,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
private NumberTextView captionLimitView;
|
||||
private int currentLimit = -1;
|
||||
private int codePointCount;
|
||||
CrossOutDrawable notifySilentDrawable;
|
||||
|
||||
|
||||
private class SeekBarWaveformView extends View {
|
||||
|
@ -353,6 +354,8 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
public ValueAnimator currentTopViewAnimation;
|
||||
private ReplaceableIconDrawable botButtonDrawablel;
|
||||
|
||||
private boolean isPaste;
|
||||
|
||||
private boolean destroyed;
|
||||
|
||||
private MessageObject editingMessageObject;
|
||||
|
@ -1771,6 +1774,14 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
}
|
||||
isInitLineCount = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTextContextMenuItem(int id) {
|
||||
if (id == android.R.id.paste) {
|
||||
isPaste = true;
|
||||
}
|
||||
return super.onTextContextMenuItem(id);
|
||||
}
|
||||
};
|
||||
messageEditText.setDelegate(() -> {
|
||||
if (delegate != null) {
|
||||
|
@ -1780,7 +1791,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
messageEditText.setWindowView(parentActivity.getWindow().getDecorView());
|
||||
TLRPC.EncryptedChat encryptedChat = parentFragment != null ? parentFragment.getCurrentEncryptedChat() : null;
|
||||
messageEditText.setAllowTextEntitiesIntersection(supportsSendingNewEntities());
|
||||
updateFieldHint();
|
||||
updateFieldHint(false);
|
||||
int flags = EditorInfo.IME_FLAG_NO_EXTRACT_UI;
|
||||
if (encryptedChat != null) {
|
||||
flags |= 0x01000000; //EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING;
|
||||
|
@ -1876,9 +1887,10 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
if (innerTextChange == 1) {
|
||||
return;
|
||||
}
|
||||
if (sendByEnter && editingMessageObject == null && count > before && charSequence.length() > 0 && count == 1 && before == 0 && charSequence.length() == start + count && charSequence.charAt(charSequence.length() - 1) == '\n') {
|
||||
if (sendByEnter && !isPaste && editingMessageObject == null && count > before && charSequence.length() > 0 && charSequence.length() == start + count && charSequence.charAt(charSequence.length() - 1) == '\n') {
|
||||
nextChangeIsSend = true;
|
||||
}
|
||||
isPaste = false;
|
||||
checkSendButton(true);
|
||||
CharSequence message = AndroidUtilities.getTrimmedString(charSequence.toString());
|
||||
if (delegate != null) {
|
||||
|
@ -2036,7 +2048,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
});
|
||||
|
||||
notifyButton = new ImageView(context);
|
||||
notifyButton.setImageResource(silent ? R.drawable.input_notify_off : R.drawable.input_notify_on);
|
||||
notifySilentDrawable = new CrossOutDrawable(context, R.drawable.input_notify_on, Theme.key_chat_messagePanelIcons);
|
||||
notifyButton.setImageDrawable(notifySilentDrawable);
|
||||
notifySilentDrawable.setCrossOut(silent, false);
|
||||
notifyButton.setContentDescription(silent ? LocaleController.getString("AccDescrChanSilentOn", R.string.AccDescrChanSilentOn) : LocaleController.getString("AccDescrChanSilentOff", R.string.AccDescrChanSilentOff));
|
||||
notifyButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_messagePanelIcons), PorterDuff.Mode.MULTIPLY));
|
||||
notifyButton.setScaleType(ImageView.ScaleType.CENTER);
|
||||
|
@ -2052,7 +2066,11 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
silent = !silent;
|
||||
notifyButton.setImageResource(silent ? R.drawable.input_notify_off : R.drawable.input_notify_on);
|
||||
if (notifySilentDrawable == null) {
|
||||
notifySilentDrawable = new CrossOutDrawable(context, R.drawable.input_notify_on, Theme.key_chat_messagePanelIcons);
|
||||
}
|
||||
notifySilentDrawable.setCrossOut(silent, true);
|
||||
notifyButton.setImageDrawable(notifySilentDrawable);
|
||||
MessagesController.getNotificationsSettings(currentAccount).edit().putBoolean("silent_" + dialog_id, silent).commit();
|
||||
NotificationsController.getInstance(currentAccount).updateServerNotificationsSettings(dialog_id);
|
||||
try {
|
||||
|
@ -2062,15 +2080,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
if (silent) {
|
||||
visibleToast = Toast.makeText(parentActivity, LocaleController.getString("ChannelNotifyMembersInfoOff", R.string.ChannelNotifyMembersInfoOff), Toast.LENGTH_SHORT);
|
||||
visibleToast.show();
|
||||
} else {
|
||||
visibleToast = Toast.makeText(parentActivity, LocaleController.getString("ChannelNotifyMembersInfoOn", R.string.ChannelNotifyMembersInfoOn), Toast.LENGTH_SHORT);
|
||||
visibleToast.show();
|
||||
}
|
||||
BulletinFactory.of(fragment).createMembersNotifyInfo(!silent).show();
|
||||
notifyButton.setContentDescription(silent ? LocaleController.getString("AccDescrChanSilentOn", R.string.AccDescrChanSilentOn) : LocaleController.getString("AccDescrChanSilentOff", R.string.AccDescrChanSilentOff));
|
||||
updateFieldHint();
|
||||
updateFieldHint(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -3434,7 +3446,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
|
||||
updateScheduleButton(false);
|
||||
checkRoundVideo();
|
||||
updateFieldHint();
|
||||
updateFieldHint(false);
|
||||
}
|
||||
|
||||
public void setChatInfo(TLRPC.ChatFull chatInfo) {
|
||||
|
@ -3495,7 +3507,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
return hasRecordVideo;
|
||||
}
|
||||
|
||||
private void updateFieldHint() {
|
||||
private void updateFieldHint(boolean animated) {
|
||||
if (editingMessageObject != null) {
|
||||
messageEditText.setHintText(editingCaption ? LocaleController.getString("Caption", R.string.Caption) : LocaleController.getString("TypeMessage", R.string.TypeMessage));
|
||||
} else {
|
||||
|
@ -3517,9 +3529,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
}
|
||||
} else if (isChannel) {
|
||||
if (silent) {
|
||||
messageEditText.setHintText(LocaleController.getString("ChannelSilentBroadcast", R.string.ChannelSilentBroadcast));
|
||||
messageEditText.setHintText(LocaleController.getString("ChannelSilentBroadcast", R.string.ChannelSilentBroadcast), animated);
|
||||
} else {
|
||||
messageEditText.setHintText(LocaleController.getString("ChannelBroadcast", R.string.ChannelBroadcast));
|
||||
messageEditText.setHintText(LocaleController.getString("ChannelBroadcast", R.string.ChannelBroadcast), animated);
|
||||
}
|
||||
} else {
|
||||
messageEditText.setHintText(LocaleController.getString("TypeMessage", R.string.TypeMessage));
|
||||
|
@ -5454,7 +5466,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
}
|
||||
updateFieldRight(1);
|
||||
}
|
||||
updateFieldHint();
|
||||
updateFieldHint(false);
|
||||
}
|
||||
|
||||
public ImageView getAttachButton() {
|
||||
|
@ -5654,7 +5666,11 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
|
|||
canWriteToChannel = ChatObject.isChannel(currentChat) && (currentChat.creator || currentChat.admin_rights != null && currentChat.admin_rights.post_messages) && !currentChat.megagroup;
|
||||
if (notifyButton != null) {
|
||||
notifyVisible = canWriteToChannel;
|
||||
notifyButton.setImageResource(silent ? R.drawable.input_notify_off : R.drawable.input_notify_on);
|
||||
if (notifySilentDrawable == null) {
|
||||
notifySilentDrawable = new CrossOutDrawable(getContext(), R.drawable.input_notify_on, Theme.key_chat_messagePanelIcons);
|
||||
}
|
||||
notifySilentDrawable.setCrossOut(silent, false);
|
||||
notifyButton.setImageDrawable(notifySilentDrawable);
|
||||
}
|
||||
if (attachLayout != null) {
|
||||
updateFieldRight(attachLayout.getVisibility() == VISIBLE ? 1 : 0);
|
||||
|
|
|
@ -1578,15 +1578,19 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
|
|||
}
|
||||
}
|
||||
fixLayoutInternal(true);
|
||||
if (checkPermission && Build.VERSION.SDK_INT >= 23) {
|
||||
Activity activity = getParentActivity();
|
||||
if (activity != null) {
|
||||
checkPermission = false;
|
||||
if (activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 2);
|
||||
boolean keyboardVisible = parentAlert.delegate.needEnterComment();
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (checkPermission && Build.VERSION.SDK_INT >= 23) {
|
||||
Activity activity = getParentActivity();
|
||||
if (activity != null) {
|
||||
checkPermission = false;
|
||||
if (activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
activity.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, keyboardVisible ? 200 : 0);
|
||||
|
||||
layoutManager.scrollToPositionWithOffset(0, 0);
|
||||
|
||||
updateClipView();
|
||||
|
|
|
@ -40,6 +40,7 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
@ -441,12 +442,19 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
|
|||
cameraDrawable = context.getResources().getDrawable(R.drawable.instant_camera).mutate();
|
||||
|
||||
ActionBarMenu menu = parentAlert.actionBar.createMenu();
|
||||
dropDownContainer = new ActionBarMenuItem(context, menu, 0, 0);
|
||||
dropDownContainer = new ActionBarMenuItem(context, menu, 0, 0) {
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
info.setText(dropDown.getText());
|
||||
}
|
||||
};
|
||||
dropDownContainer.setSubMenuOpenSide(1);
|
||||
parentAlert.actionBar.addView(dropDownContainer, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, AndroidUtilities.isTablet() ? 64 : 56, 0, 40, 0));
|
||||
dropDownContainer.setOnClickListener(view -> dropDownContainer.toggleSubMenu());
|
||||
|
||||
dropDown = new TextView(context);
|
||||
dropDown.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
|
||||
dropDown.setGravity(Gravity.LEFT);
|
||||
dropDown.setSingleLine(true);
|
||||
dropDown.setLines(1);
|
||||
|
|
|
@ -264,14 +264,14 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
|
|||
}
|
||||
|
||||
public void setTitle(CharSequence value) {
|
||||
setTitle(value, false);
|
||||
setTitle(value, false, false);
|
||||
}
|
||||
|
||||
public void setTitle(CharSequence value, boolean scam) {
|
||||
public void setTitle(CharSequence value, boolean scam, boolean fake) {
|
||||
titleTextView.setText(value);
|
||||
if (scam) {
|
||||
if (scam || fake) {
|
||||
if (!(titleTextView.getRightDrawable() instanceof ScamDrawable)) {
|
||||
ScamDrawable drawable = new ScamDrawable(11);
|
||||
ScamDrawable drawable = new ScamDrawable(11, scam ? 0 : 1);
|
||||
drawable.setColor(Theme.getColor(Theme.key_actionBarDefaultSubtitle));
|
||||
titleTextView.setRightDrawable(drawable);
|
||||
}
|
||||
|
|
|
@ -8,12 +8,14 @@ import android.widget.LinearLayout;
|
|||
import android.widget.TextView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.DocumentObject;
|
||||
import org.telegram.messenger.Emoji;
|
||||
import org.telegram.messenger.FileLoader;
|
||||
import org.telegram.messenger.ImageLocation;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.SvgHelper;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.tgnet.ConnectionsManager;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
|
@ -53,8 +55,13 @@ public class ChatGreetingsView extends LinearLayout {
|
|||
|
||||
updateColors();
|
||||
|
||||
titleView.setText(LocaleController.formatString("NearbyPeopleGreetingsMessage", R.string.NearbyPeopleGreetingsMessage, user.first_name, LocaleController.formatDistance(distance, 1)));
|
||||
descriptionView.setText(LocaleController.getString("NearbyPeopleGreetingsDescription", R.string.NearbyPeopleGreetingsDescription));
|
||||
if (distance <= 0) {
|
||||
titleView.setText(LocaleController.getString("NoMessages", R.string.NoMessages));
|
||||
descriptionView.setText(LocaleController.getString("NoMessagesGreetingsDescription", R.string.NoMessagesGreetingsDescription));
|
||||
} else {
|
||||
titleView.setText(LocaleController.formatString("NearbyPeopleGreetingsMessage", R.string.NearbyPeopleGreetingsMessage, user.first_name, LocaleController.formatDistance(distance, 1)));
|
||||
descriptionView.setText(LocaleController.getString("NearbyPeopleGreetingsDescription", R.string.NearbyPeopleGreetingsDescription));
|
||||
}
|
||||
|
||||
if (preloadedGreetingsSticker == null) {
|
||||
TLRPC.TL_messages_getStickers req = new TLRPC.TL_messages_getStickers();
|
||||
|
@ -64,27 +71,23 @@ public class ChatGreetingsView extends LinearLayout {
|
|||
ArrayList<TLRPC.Document> list = ((TLRPC.TL_messages_stickers) response).stickers;
|
||||
if (!list.isEmpty()) {
|
||||
TLRPC.Document sticker = list.get(Math.abs(new Random().nextInt() % list.size()));
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
setSticker(sticker);
|
||||
});
|
||||
AndroidUtilities.runOnUIThread(() -> setSticker(sticker));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
setSticker(preloadedGreetingsSticker);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSticker(TLRPC.Document sticker) {
|
||||
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(sticker.thumbs, 90);
|
||||
|
||||
|
||||
stickerToSendView.setImage(
|
||||
ImageLocation.getForDocument(sticker), createFilter(sticker),
|
||||
ImageLocation.getForDocument(thumb, sticker), null,
|
||||
0, sticker
|
||||
);
|
||||
SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(sticker, Theme.key_chat_serviceBackground, 1.0f);
|
||||
if (svgThumb != null) {
|
||||
stickerToSendView.setImage(ImageLocation.getForDocument(sticker), createFilter(sticker), svgThumb, 0, sticker);
|
||||
} else {
|
||||
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(sticker.thumbs, 90);
|
||||
stickerToSendView.setImage(ImageLocation.getForDocument(sticker), createFilter(sticker), ImageLocation.getForDocument(thumb, sticker), null, 0, sticker);
|
||||
}
|
||||
stickerToSendView.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onGreetings(sticker);
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Cells.ChatMessageCell;
|
||||
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
public class ChecksHintView extends FrameLayout {
|
||||
|
||||
private TextView[] textView = new TextView[2];
|
||||
private RLottieImageView[] imageView = new RLottieImageView[2];
|
||||
private ImageView arrowImageView;
|
||||
private ChatMessageCell messageCell;
|
||||
private View currentView;
|
||||
private AnimatorSet animatorSet;
|
||||
private Runnable hideRunnable;
|
||||
private float translationY;
|
||||
|
||||
private long showingDuration = 2000;
|
||||
|
||||
public ChecksHintView(Context context) {
|
||||
super(context);
|
||||
|
||||
FrameLayout backgroundView = new FrameLayout(context);
|
||||
backgroundView.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(6), Theme.getColor(Theme.key_chat_gifSaveHintBackground)));
|
||||
backgroundView.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8));
|
||||
addView(backgroundView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 6));
|
||||
|
||||
for (int a = 0; a < 2; a++) {
|
||||
imageView[a] = new RLottieImageView(context);
|
||||
imageView[a].setScaleType(ImageView.ScaleType.CENTER);
|
||||
backgroundView.addView(imageView[a], LayoutHelper.createFrame(24, 24, Gravity.LEFT | Gravity.TOP, 0, a == 0 ? 0 : 24, 0, 0));
|
||||
|
||||
textView[a] = new TextView(context);
|
||||
textView[a].setTextColor(Theme.getColor(Theme.key_chat_gifSaveHintText));
|
||||
textView[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
textView[a].setMaxLines(1);
|
||||
textView[a].setSingleLine(true);
|
||||
textView[a].setMaxWidth(AndroidUtilities.dp(250));
|
||||
textView[a].setGravity(Gravity.LEFT | Gravity.TOP);
|
||||
textView[a].setPivotX(0);
|
||||
backgroundView.addView(textView[a], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 32, a == 0 ? 2 : 26, 10, 0));
|
||||
|
||||
if (a == 0) {
|
||||
imageView[a].setAnimation(R.raw.ticks_single, 24, 24);
|
||||
textView[a].setText(LocaleController.getString("HintSent", R.string.HintSent));
|
||||
} else {
|
||||
imageView[a].setAnimation(R.raw.ticks_double, 24, 24);
|
||||
textView[a].setText(LocaleController.getString("HintRead", R.string.HintRead));
|
||||
}
|
||||
imageView[a].playAnimation();
|
||||
}
|
||||
|
||||
arrowImageView = new ImageView(context);
|
||||
arrowImageView.setImageResource(R.drawable.tooltip_arrow);
|
||||
arrowImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_gifSaveHintBackground), PorterDuff.Mode.MULTIPLY));
|
||||
addView(arrowImageView, LayoutHelper.createFrame(14, 6, Gravity.LEFT | Gravity.BOTTOM, 0, 0, 0, 0));
|
||||
}
|
||||
|
||||
public float getBaseTranslationY() {
|
||||
return translationY;
|
||||
}
|
||||
|
||||
public boolean showForMessageCell(ChatMessageCell cell, boolean animated) {
|
||||
if (hideRunnable != null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(hideRunnable);
|
||||
hideRunnable = null;
|
||||
}
|
||||
int[] position = new int[2];
|
||||
cell.getLocationInWindow(position);
|
||||
int top = position[1];
|
||||
View p = (View) getParent();
|
||||
p.getLocationInWindow(position);
|
||||
top -= position[1];
|
||||
|
||||
View parentView = (View) cell.getParent();
|
||||
|
||||
measure(MeasureSpec.makeMeasureSpec(1000, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(1000, MeasureSpec.AT_MOST));
|
||||
|
||||
if (top <= getMeasuredHeight() + AndroidUtilities.dp(10)) {
|
||||
return false;
|
||||
}
|
||||
top += cell.getChecksY() + AndroidUtilities.dp(6);
|
||||
int centerX = cell.getChecksX() + AndroidUtilities.dp(5);
|
||||
|
||||
int parentWidth = parentView.getMeasuredWidth();
|
||||
setTranslationY(translationY = top - getMeasuredHeight());
|
||||
int iconX = cell.getLeft() + centerX;
|
||||
int left = AndroidUtilities.dp(15);
|
||||
if (iconX > parentView.getMeasuredWidth() / 2) {
|
||||
int offset = parentWidth - getMeasuredWidth() - AndroidUtilities.dp(20);
|
||||
setTranslationX(offset);
|
||||
left += offset;
|
||||
} else {
|
||||
setTranslationX(0);
|
||||
}
|
||||
float arrowX = cell.getLeft() + centerX - left - arrowImageView.getMeasuredWidth() / 2;
|
||||
arrowImageView.setTranslationX(arrowX);
|
||||
if (iconX > parentView.getMeasuredWidth() / 2) {
|
||||
if (arrowX < AndroidUtilities.dp(10)) {
|
||||
float diff = arrowX - AndroidUtilities.dp(10);
|
||||
setTranslationX(getTranslationX() + diff);
|
||||
arrowImageView.setTranslationX(arrowX - diff);
|
||||
}
|
||||
} else {
|
||||
if (arrowX > getMeasuredWidth() - AndroidUtilities.dp(14 + 10)) {
|
||||
float diff = arrowX - getMeasuredWidth() + AndroidUtilities.dp(14 + 10);
|
||||
setTranslationX(diff);
|
||||
arrowImageView.setTranslationX(arrowX - diff);
|
||||
} else if (arrowX < AndroidUtilities.dp(10)) {
|
||||
float diff = arrowX - AndroidUtilities.dp(10);
|
||||
setTranslationX(getTranslationX() + diff);
|
||||
arrowImageView.setTranslationX(arrowX - diff);
|
||||
}
|
||||
}
|
||||
setPivotX(arrowX);
|
||||
setPivotY(getMeasuredHeight());
|
||||
|
||||
messageCell = cell;
|
||||
if (animatorSet != null) {
|
||||
animatorSet.cancel();
|
||||
animatorSet = null;
|
||||
}
|
||||
|
||||
setTag(1);
|
||||
setVisibility(VISIBLE);
|
||||
if (animated) {
|
||||
animatorSet = new AnimatorSet();
|
||||
animatorSet.playTogether(
|
||||
ObjectAnimator.ofFloat(this, View.ALPHA, 0.0f, 1.0f),
|
||||
ObjectAnimator.ofFloat(this, View.SCALE_X, 0.0f, 1.0f),
|
||||
ObjectAnimator.ofFloat(this, View.SCALE_Y, 0.0f, 1.0f)
|
||||
);
|
||||
animatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
animatorSet = null;
|
||||
AndroidUtilities.runOnUIThread(hideRunnable = () -> hide(), 3000);
|
||||
}
|
||||
});
|
||||
animatorSet.setDuration(180);
|
||||
animatorSet.start();
|
||||
|
||||
for (int a = 0; a < 2; a++) {
|
||||
final int num = a;
|
||||
textView[a].animate().scaleX(1.04f).scaleY(1.04f).setInterpolator(CubicBezierInterpolator.EASE_IN).setStartDelay((a == 0 ? 132 : 500) + 140).setDuration(100).setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
textView[num].animate().scaleX(1.0f).scaleY(1.0f).setInterpolator(CubicBezierInterpolator.EASE_OUT).setStartDelay(0).setDuration(100).start();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
} else {
|
||||
setAlpha(1.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
if (getTag() == null) {
|
||||
return;
|
||||
}
|
||||
setTag(null);
|
||||
if (hideRunnable != null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(hideRunnable);
|
||||
hideRunnable = null;
|
||||
}
|
||||
if (animatorSet != null) {
|
||||
animatorSet.cancel();
|
||||
animatorSet = null;
|
||||
}
|
||||
animatorSet = new AnimatorSet();
|
||||
animatorSet.playTogether(
|
||||
ObjectAnimator.ofFloat(this, View.ALPHA, 0.0f),
|
||||
ObjectAnimator.ofFloat(this, View.SCALE_X, 0.0f),
|
||||
ObjectAnimator.ofFloat(this, View.SCALE_Y, 0.0f)
|
||||
);
|
||||
animatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
setVisibility(View.INVISIBLE);
|
||||
currentView = null;
|
||||
messageCell = null;
|
||||
animatorSet = null;
|
||||
}
|
||||
});
|
||||
animatorSet.setDuration(180);
|
||||
animatorSet.start();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.text.Layout;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
|
||||
public class CounterView extends View {
|
||||
|
||||
private final static int ANIMATION_TYPE_IN = 0;
|
||||
private final static int ANIMATION_TYPE_OUT = 1;
|
||||
private final static int ANIMATION_TYPE_REPLACE = 2;
|
||||
|
||||
int animationType = -1;
|
||||
|
||||
Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
RectF rectF = new RectF();
|
||||
|
||||
int currentCount;
|
||||
private boolean countAnimationIncrement;
|
||||
private ValueAnimator countAnimator;
|
||||
private float countChangeProgress = 1f;
|
||||
private StaticLayout countLayout;
|
||||
private StaticLayout countOldLayout;
|
||||
private StaticLayout countAnimationStableLayout;
|
||||
private StaticLayout countAnimationInLayout;
|
||||
|
||||
private int countWidthOld;
|
||||
private int countWidth;
|
||||
|
||||
private int circleColor;
|
||||
private int textColor;
|
||||
private String textColorKey = Theme.key_chat_goDownButtonCounter;
|
||||
private String circleColorKey = Theme.key_chat_goDownButtonCounterBackground;
|
||||
|
||||
int lastH;
|
||||
int gravity = Gravity.CENTER;
|
||||
float countLeft;
|
||||
float x;
|
||||
|
||||
private boolean reverseAnimation;
|
||||
public float horizontalPadding;
|
||||
|
||||
|
||||
public CounterView(Context context) {
|
||||
super(context);
|
||||
setVisibility(View.GONE);
|
||||
circlePaint.setColor(Color.BLACK);
|
||||
|
||||
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
textPaint.setTextSize(AndroidUtilities.dp(13));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (getMeasuredHeight() != lastH) {
|
||||
int count = currentCount;
|
||||
currentCount = -1;
|
||||
setCount(count, animationType == ANIMATION_TYPE_IN);
|
||||
lastH = getMeasuredHeight();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCount(int count, boolean animated) {
|
||||
if (count == currentCount) {
|
||||
return;
|
||||
}
|
||||
if (countAnimator != null) {
|
||||
countAnimator.cancel();
|
||||
}
|
||||
if (count > 0) {
|
||||
setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (!animated) {
|
||||
currentCount = count;
|
||||
if (count == 0) {
|
||||
setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
String newStr = String.valueOf(count);
|
||||
countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(newStr)));
|
||||
countLayout = new StaticLayout(newStr, textPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
|
||||
invalidate();
|
||||
}
|
||||
String newStr = String.valueOf(count);
|
||||
|
||||
if (animated) {
|
||||
if (countAnimator != null) {
|
||||
countAnimator.cancel();
|
||||
}
|
||||
countChangeProgress = 0f;
|
||||
countAnimator = ValueAnimator.ofFloat(0, 1f);
|
||||
countAnimator.addUpdateListener(valueAnimator -> {
|
||||
countChangeProgress = (float) valueAnimator.getAnimatedValue();
|
||||
invalidate();
|
||||
});
|
||||
countAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
animationType = -1;
|
||||
countChangeProgress = 1f;
|
||||
countOldLayout = null;
|
||||
countAnimationStableLayout = null;
|
||||
countAnimationInLayout = null;
|
||||
if (currentCount == 0) {
|
||||
setVisibility(View.GONE);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
});
|
||||
if (currentCount <= 0) {
|
||||
animationType = ANIMATION_TYPE_IN;
|
||||
countAnimator.setDuration(220);
|
||||
countAnimator.setInterpolator(new OvershootInterpolator());
|
||||
} else if (count == 0) {
|
||||
animationType = ANIMATION_TYPE_OUT;
|
||||
countAnimator.setDuration(150);
|
||||
countAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
} else {
|
||||
animationType = ANIMATION_TYPE_REPLACE;
|
||||
countAnimator.setDuration(430);
|
||||
countAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
}
|
||||
if (countLayout != null) {
|
||||
String oldStr = String.valueOf(currentCount);
|
||||
|
||||
if (oldStr.length() == newStr.length()) {
|
||||
SpannableStringBuilder oldSpannableStr = new SpannableStringBuilder(oldStr);
|
||||
SpannableStringBuilder newSpannableStr = new SpannableStringBuilder(newStr);
|
||||
SpannableStringBuilder stableStr = new SpannableStringBuilder(newStr);
|
||||
for (int i = 0; i < oldStr.length(); i++) {
|
||||
if (oldStr.charAt(i) == newStr.charAt(i)) {
|
||||
oldSpannableStr.setSpan(new EmptyStubSpan(), i, i + 1, 0);
|
||||
newSpannableStr.setSpan(new EmptyStubSpan(), i, i + 1, 0);
|
||||
} else {
|
||||
stableStr.setSpan(new EmptyStubSpan(), i, i + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int countOldWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(oldStr)));
|
||||
countOldLayout = new StaticLayout(oldSpannableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
|
||||
countAnimationStableLayout = new StaticLayout(stableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
|
||||
countAnimationInLayout = new StaticLayout(newSpannableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
|
||||
} else {
|
||||
countOldLayout = countLayout;
|
||||
}
|
||||
}
|
||||
countWidthOld = countWidth;
|
||||
countAnimationIncrement = count > currentCount;
|
||||
countAnimator.start();
|
||||
}
|
||||
if (count > 0) {
|
||||
countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(newStr)));
|
||||
countLayout = new StaticLayout(newStr, textPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
|
||||
}
|
||||
|
||||
currentCount = count;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
int textColor = Theme.getColor(textColorKey);
|
||||
int circleColor = Theme.getColor(circleColorKey);
|
||||
if (this.textColor != textColor) {
|
||||
this.textColor = textColor;
|
||||
textPaint.setColor(textColor);
|
||||
}
|
||||
if (this.circleColor != circleColor) {
|
||||
this.circleColor = circleColor;
|
||||
circlePaint.setColor(circleColor);
|
||||
}
|
||||
if (countChangeProgress != 1f) {
|
||||
if (animationType == ANIMATION_TYPE_IN || animationType == ANIMATION_TYPE_OUT) {
|
||||
updateX(countWidth);
|
||||
float cx = countLeft + countWidth / 2f;
|
||||
float cy = getMeasuredHeight() / 2f;
|
||||
canvas.save();
|
||||
float progress = animationType == ANIMATION_TYPE_IN ? countChangeProgress : (1f - countChangeProgress);
|
||||
canvas.scale(progress, progress, cx, cy);
|
||||
drawInternal(canvas);
|
||||
canvas.restore();
|
||||
} else {
|
||||
float progressHalf = countChangeProgress * 2;
|
||||
if (progressHalf > 1f) {
|
||||
progressHalf = 1f;
|
||||
}
|
||||
|
||||
float countTop = (getMeasuredHeight() - AndroidUtilities.dp(23)) / 2f;
|
||||
float countWidth;
|
||||
if (this.countWidth == this.countWidthOld) {
|
||||
countWidth = this.countWidth;
|
||||
} else {
|
||||
countWidth = this.countWidth * progressHalf + this.countWidthOld * (1f - progressHalf);
|
||||
}
|
||||
updateX(countWidth);
|
||||
|
||||
float scale = 1f;
|
||||
if (countAnimationIncrement) {
|
||||
if (countChangeProgress <= 0.5f) {
|
||||
scale += 0.1f * CubicBezierInterpolator.EASE_OUT.getInterpolation(countChangeProgress * 2);
|
||||
} else {
|
||||
scale += 0.1f * CubicBezierInterpolator.EASE_IN.getInterpolation((1f - (countChangeProgress - 0.5f) * 2));
|
||||
}
|
||||
}
|
||||
|
||||
rectF.set(x, countTop, x + countWidth + AndroidUtilities.dp(11), countTop + AndroidUtilities.dp(23));
|
||||
canvas.save();
|
||||
canvas.scale(scale, scale, rectF.centerX(), rectF.centerY());
|
||||
canvas.drawRoundRect(rectF, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, circlePaint);
|
||||
canvas.clipRect(rectF);
|
||||
|
||||
boolean increment = reverseAnimation != countAnimationIncrement;
|
||||
if (countAnimationInLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(countLeft, countTop + AndroidUtilities.dp(4) + (increment ? AndroidUtilities.dp(13) : -AndroidUtilities.dp(13)) * (1f - progressHalf));
|
||||
textPaint.setAlpha((int) (255 * progressHalf));
|
||||
countAnimationInLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
} else if (countLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(countLeft, countTop + AndroidUtilities.dp(4) + (increment ? AndroidUtilities.dp(13) : -AndroidUtilities.dp(13)) * (1f - progressHalf));
|
||||
textPaint.setAlpha((int) (255 * progressHalf));
|
||||
countLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
if (countOldLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(countLeft, countTop + AndroidUtilities.dp(4) + (increment ? -AndroidUtilities.dp(13) : AndroidUtilities.dp(13)) * (progressHalf));
|
||||
textPaint.setAlpha((int) (255 * (1f - progressHalf)));
|
||||
countOldLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
if (countAnimationStableLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(countLeft, countTop + AndroidUtilities.dp(4));
|
||||
textPaint.setAlpha(255);
|
||||
countAnimationStableLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
textPaint.setAlpha(255);
|
||||
canvas.restore();
|
||||
}
|
||||
} else {
|
||||
drawInternal(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateX(float countWidth) {
|
||||
if (gravity == Gravity.RIGHT) {
|
||||
countLeft = getMeasuredWidth() - AndroidUtilities.dp(5.5f);
|
||||
if (horizontalPadding != 0) {
|
||||
countLeft -= Math.max(horizontalPadding + countWidth / 2f, countWidth);
|
||||
} else {
|
||||
countLeft -= countWidth;
|
||||
}
|
||||
} else if (gravity == Gravity.LEFT) {
|
||||
countLeft = AndroidUtilities.dp(5.5f);
|
||||
} else {
|
||||
countLeft = (int) ((getMeasuredWidth() - countWidth) / 2f);
|
||||
}
|
||||
x = countLeft - AndroidUtilities.dp(5.5f);
|
||||
}
|
||||
|
||||
private void drawInternal(Canvas canvas) {
|
||||
float countTop = (getMeasuredHeight() - AndroidUtilities.dp(23)) / 2f;
|
||||
updateX(countWidth);
|
||||
rectF.set(x, countTop, x + countWidth + AndroidUtilities.dp(11), countTop + AndroidUtilities.dp(23));
|
||||
canvas.drawRoundRect(rectF, 11.5f * AndroidUtilities.density, 11.5f * AndroidUtilities.density, circlePaint);
|
||||
if (countLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(countLeft, countTop + AndroidUtilities.dp(4));
|
||||
countLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
public void setColors(String textKey, String circleKey){
|
||||
this.textColorKey = textKey;
|
||||
this.circleColorKey = circleKey;
|
||||
}
|
||||
|
||||
public void setGravity(int gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
public void setReverse(boolean b) {
|
||||
reverseAnimation = b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
|
||||
public class CrossOutDrawable extends Drawable {
|
||||
|
||||
Drawable iconDrawable;
|
||||
RectF rectF = new RectF();
|
||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
final Paint xRefPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
int color;
|
||||
String colorKey;
|
||||
float progress;
|
||||
boolean cross;
|
||||
|
||||
public CrossOutDrawable(Context context, int iconRes, String colorKey) {
|
||||
iconDrawable = ContextCompat.getDrawable(context, iconRes);
|
||||
this.colorKey = colorKey;
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setStrokeWidth(AndroidUtilities.dpf2(1.7f));
|
||||
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||
xRefPaint.setColor(0xff000000);
|
||||
xRefPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||
xRefPaint.setStyle(Paint.Style.STROKE);
|
||||
xRefPaint.setStrokeWidth(AndroidUtilities.dpf2(2.5f));
|
||||
}
|
||||
|
||||
public void setCrossOut(boolean cross, boolean animated) {
|
||||
this.cross = cross;
|
||||
if (!animated) {
|
||||
progress = cross ? 1f : 0f;
|
||||
} else {
|
||||
progress = cross ? 0f : 1f;
|
||||
}
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
if (cross && progress != 1f) {
|
||||
progress += 16f / 150f;
|
||||
invalidateSelf();
|
||||
if (progress > 1f) {
|
||||
progress = 1f;
|
||||
}
|
||||
} else if (!cross && progress != 0f) {
|
||||
progress -= 16f / 150f;
|
||||
invalidateSelf();
|
||||
if (progress < 0) {
|
||||
progress = 0;
|
||||
}
|
||||
}
|
||||
if (progress == 0) {
|
||||
iconDrawable.draw(canvas);
|
||||
return;
|
||||
}
|
||||
int newColor = Theme.getColor(colorKey);
|
||||
if (color != newColor) {
|
||||
color = newColor;
|
||||
paint.setColor(newColor);
|
||||
}
|
||||
rectF.set(iconDrawable.getBounds());
|
||||
canvas.saveLayerAlpha(rectF, 255, Canvas.ALL_SAVE_FLAG);
|
||||
iconDrawable.draw(canvas);
|
||||
|
||||
float startX = rectF.left + AndroidUtilities.dpf2(4.5f);
|
||||
float startY = rectF.top + AndroidUtilities.dpf2(4.5f) - AndroidUtilities.dp(1);
|
||||
float stopX = rectF.right - AndroidUtilities.dp(3);
|
||||
float stopY = rectF.bottom - AndroidUtilities.dp(1) - AndroidUtilities.dp(3);
|
||||
if (cross) {
|
||||
stopX = startX + (stopX - startX) * progress;
|
||||
stopY = startY + (stopY - startY) * progress;
|
||||
} else {
|
||||
startX = startX + (stopX - startX) * (1f - progress);
|
||||
startY = startY + (stopY - startY) * (1f - progress);
|
||||
}
|
||||
canvas.drawLine(startX, startY - paint.getStrokeWidth(), stopX, stopY - paint.getStrokeWidth(), xRefPaint);
|
||||
canvas.drawLine(startX, startY, stopX, stopY, paint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(int left, int top, int right, int bottom) {
|
||||
super.setBounds(left, top, right, bottom);
|
||||
iconDrawable.setBounds(left, top, right, bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(@Nullable ColorFilter colorFilter) {
|
||||
iconDrawable.setColorFilter(colorFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return iconDrawable.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return iconDrawable.getIntrinsicWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
|
||||
public void setColorKey(String colorKey) {
|
||||
this.colorKey = colorKey;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.text.style.ReplacementSpan;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
|
||||
public class DotDividerSpan extends ReplacementSpan {
|
||||
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
int color;
|
||||
int topPadding;
|
||||
|
||||
@Override
|
||||
public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) {
|
||||
return AndroidUtilities.dp(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
|
||||
if (color != paint.getColor()) {
|
||||
p.setColor(paint.getColor());
|
||||
}
|
||||
float radius = AndroidUtilities.dpf2(3) / 2f;
|
||||
canvas.drawCircle(x + radius, (bottom - top) / 2 + topPadding, radius, p);
|
||||
}
|
||||
|
||||
public void setTopPadding(int topPadding) {
|
||||
this.topPadding = topPadding;
|
||||
}
|
||||
}
|
|
@ -8,8 +8,11 @@
|
|||
|
||||
package org.telegram.ui.Components;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
|
@ -28,6 +31,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
|
||||
import android.text.Layout;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
|
@ -42,6 +46,7 @@ import android.widget.EditText;
|
|||
import android.widget.TextView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.Emoji;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.R;
|
||||
|
@ -65,6 +70,7 @@ public class EditTextBoldCursor extends EditText {
|
|||
private Object editor;
|
||||
|
||||
private GradientDrawable gradientDrawable;
|
||||
private SubstringLayoutAnimator hintAnimator;
|
||||
|
||||
private Runnable invalidateRunnable = new Runnable() {
|
||||
@Override
|
||||
|
@ -391,9 +397,26 @@ public class EditTextBoldCursor extends EditText {
|
|||
}
|
||||
|
||||
public void setHintText(CharSequence text) {
|
||||
setHintText(text, false);
|
||||
}
|
||||
|
||||
public void setHintText(CharSequence text, boolean animated) {
|
||||
if (text == null) {
|
||||
text = "";
|
||||
}
|
||||
if (getMeasuredWidth() == 0) {
|
||||
animated = false;
|
||||
}
|
||||
if (animated) {
|
||||
if (hintAnimator == null) {
|
||||
hintAnimator = new SubstringLayoutAnimator(this);
|
||||
}
|
||||
hintAnimator.create(hintLayout, hint, text, getPaint());
|
||||
} else {
|
||||
if (hintAnimator != null) {
|
||||
hintAnimator.cancel();
|
||||
}
|
||||
}
|
||||
hint = text;
|
||||
if (getMeasuredWidth() != 0) {
|
||||
text = TextUtils.ellipsize(text, getPaint(), getMeasuredWidth(), TextUtils.TruncateAt.END);
|
||||
|
@ -561,7 +584,14 @@ public class EditTextBoldCursor extends EditText {
|
|||
getPaint().setColor(hintColor);
|
||||
getPaint().setAlpha((int) (255 * hintAlpha * (Color.alpha(hintColor) / 255.0f)));
|
||||
}
|
||||
hintLayout.draw(canvas);
|
||||
if (hintAnimator != null && hintAnimator.animateTextChange) {
|
||||
canvas.save();
|
||||
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
|
||||
hintAnimator.draw(canvas, getPaint());
|
||||
canvas.restore();
|
||||
} else {
|
||||
hintLayout.draw(canvas);
|
||||
}
|
||||
getPaint().setColor(oldColor);
|
||||
canvas.restore();
|
||||
}
|
||||
|
|
|
@ -126,11 +126,6 @@ public class EditTextEmoji extends FrameLayout implements NotificationCenter.Not
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImeOptions(int imeOptions) {
|
||||
super.setImeOptions(imeOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLineCountChanged(int oldLineCount, int newLineCount) {
|
||||
EditTextEmoji.this.onLineCountChanged(oldLineCount, newLineCount);
|
||||
|
|
|
@ -1027,6 +1027,15 @@ public class EmbedBottomSheet extends BottomSheet {
|
|||
dismissInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissInternal() {
|
||||
super.dismissInternal();
|
||||
if (orientationEventListener != null) {
|
||||
orientationEventListener.disable();
|
||||
orientationEventListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void exitFromPip() {
|
||||
if (webView == null || pipVideoView == null) {
|
||||
return;
|
||||
|
|
|
@ -26,15 +26,24 @@ import org.telegram.ui.ActionBar.Theme;
|
|||
public class EmptyTextProgressView extends FrameLayout {
|
||||
|
||||
private TextView textView;
|
||||
private RadialProgressView progressBar;
|
||||
private View progressView;
|
||||
private boolean inLayout;
|
||||
private int showAtPos;
|
||||
|
||||
public EmptyTextProgressView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public EmptyTextProgressView(Context context, View progressView) {
|
||||
super(context);
|
||||
|
||||
progressBar = new RadialProgressView(context);
|
||||
addView(progressBar, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
|
||||
if (progressView == null) {
|
||||
progressView = new RadialProgressView(context);
|
||||
addView(progressView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
|
||||
} else {
|
||||
addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
}
|
||||
this.progressView = progressView;
|
||||
|
||||
textView = new TextView(context);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
|
@ -44,7 +53,7 @@ public class EmptyTextProgressView extends FrameLayout {
|
|||
textView.setText(LocaleController.getString("NoResult", R.string.NoResult));
|
||||
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
|
||||
|
||||
progressBar.setAlpha(0f);
|
||||
progressView.setAlpha(0f);
|
||||
textView.setAlpha(0f);
|
||||
|
||||
setOnTouchListener((v, event) -> true);
|
||||
|
@ -52,12 +61,12 @@ public class EmptyTextProgressView extends FrameLayout {
|
|||
|
||||
public void showProgress() {
|
||||
textView.animate().alpha(0f).setDuration(150).start();
|
||||
progressBar.animate().alpha(1f).setDuration(150).start();
|
||||
progressView.animate().alpha(1f).setDuration(150).start();
|
||||
}
|
||||
|
||||
public void showTextView() {
|
||||
textView.animate().alpha(1f).setDuration(150).start();
|
||||
progressBar.animate().alpha(0f).setDuration(150).start();
|
||||
progressView.animate().alpha(0f).setDuration(150).start();
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
|
@ -69,7 +78,9 @@ public class EmptyTextProgressView extends FrameLayout {
|
|||
}
|
||||
|
||||
public void setProgressBarColor(int color) {
|
||||
progressBar.setProgressColor(color);
|
||||
if (progressView instanceof RadialProgressView) {
|
||||
((RadialProgressView) progressView).setProgressColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTopImage(int resId) {
|
||||
|
|
|
@ -556,6 +556,7 @@ public class FilterTabsView extends FrameLayout {
|
|||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
info.setSelected(currentTab != null && selectedTabId != -1 && currentTab.id == selectedTabId);
|
||||
info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_LONG_CLICK, LocaleController.getString("AccDescrOpenMenu2", R.string.AccDescrOpenMenu2)));
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.graphics.Canvas;
|
|||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.os.SystemClock;
|
||||
|
@ -12,6 +13,7 @@ import android.view.View;
|
|||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.SharedConfig;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
|
||||
public class FlickerLoadingView extends View {
|
||||
|
@ -22,6 +24,10 @@ public class FlickerLoadingView extends View {
|
|||
public final static int AUDIO_TYPE = 4;
|
||||
public final static int LINKS_TYPE = 5;
|
||||
public final static int USERS_TYPE = 6;
|
||||
public final static int DIALOG_CELL_TYPE = 7;
|
||||
public final static int CALL_LOG_TYPE = 8;
|
||||
public final static int INVITE_LINKS_TYPE = 9;
|
||||
public final static int USERS2_TYPE = 10;
|
||||
|
||||
private int gradientWidth;
|
||||
private LinearGradient gradient;
|
||||
|
@ -40,10 +46,13 @@ public class FlickerLoadingView extends View {
|
|||
private boolean isSingleCell;
|
||||
|
||||
private int viewType;
|
||||
private int paddingTop;
|
||||
private int paddingLeft;
|
||||
|
||||
private String colorKey1 = Theme.key_windowBackgroundWhite;
|
||||
private String colorKey2 = Theme.key_windowBackgroundGray;
|
||||
private String colorKey3;
|
||||
private int itemsCount = 1;
|
||||
|
||||
public void setViewType(int type) {
|
||||
this.viewType = type;
|
||||
|
@ -77,7 +86,11 @@ public class FlickerLoadingView extends View {
|
|||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (isSingleCell) {
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(getCellHeight(MeasureSpec.getSize(widthMeasureSpec)), MeasureSpec.EXACTLY));
|
||||
if (itemsCount > 1 && MeasureSpec.getSize(heightMeasureSpec) > 0) {
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Math.min(MeasureSpec.getSize(heightMeasureSpec), getCellHeight(MeasureSpec.getSize(widthMeasureSpec)) * itemsCount), MeasureSpec.EXACTLY));
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(getCellHeight(MeasureSpec.getSize(widthMeasureSpec)), MeasureSpec.EXACTLY));
|
||||
}
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
@ -98,7 +111,7 @@ public class FlickerLoadingView extends View {
|
|||
paint.setShader(gradient);
|
||||
}
|
||||
|
||||
int h = 0;
|
||||
int h = paddingTop;
|
||||
if (useHeaderOffset) {
|
||||
h += AndroidUtilities.dp(32);
|
||||
if (colorKey3 != null) {
|
||||
|
@ -106,8 +119,42 @@ public class FlickerLoadingView extends View {
|
|||
}
|
||||
canvas.drawRect(0,0, getMeasuredWidth(), AndroidUtilities.dp(32), colorKey3 != null ? headerPaint : paint);
|
||||
}
|
||||
if (getViewType() == DIALOG_TYPE) {
|
||||
while (h < getMeasuredHeight()) {
|
||||
if (getViewType() == DIALOG_CELL_TYPE) {
|
||||
int k = 0;
|
||||
while (h <= getMeasuredHeight()) {
|
||||
int childH = getCellHeight(getMeasuredWidth());
|
||||
int r = AndroidUtilities.dp(28);
|
||||
canvas.drawCircle(checkRtl(AndroidUtilities.dp(10) + r), h + (childH >> 1), r, paint);
|
||||
|
||||
rectF.set(AndroidUtilities.dp(76), h + AndroidUtilities.dp(16), AndroidUtilities.dp(148), h + AndroidUtilities.dp(24));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
||||
rectF.set(AndroidUtilities.dp(76), h + AndroidUtilities.dp(38), AndroidUtilities.dp(268), h + AndroidUtilities.dp(46));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
||||
if (SharedConfig.useThreeLinesLayout) {
|
||||
rectF.set(AndroidUtilities.dp(76), h + AndroidUtilities.dp(46 + 8), AndroidUtilities.dp(220), h + AndroidUtilities.dp(46 + 8 + 8));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
}
|
||||
|
||||
if (showDate) {
|
||||
rectF.set(getMeasuredWidth() - AndroidUtilities.dp(50), h + AndroidUtilities.dp(16), getMeasuredWidth() - AndroidUtilities.dp(12), h + AndroidUtilities.dp(24));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
}
|
||||
|
||||
h += getCellHeight(getMeasuredWidth());
|
||||
k++;
|
||||
if (isSingleCell && k >= itemsCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (getViewType() == DIALOG_TYPE) {
|
||||
int k = 0;
|
||||
while (h <= getMeasuredHeight()) {
|
||||
int r = AndroidUtilities.dp(25);
|
||||
canvas.drawCircle(checkRtl(AndroidUtilities.dp(9) + r), h + (AndroidUtilities.dp(78) >> 1), r, paint);
|
||||
|
||||
|
@ -126,7 +173,8 @@ public class FlickerLoadingView extends View {
|
|||
}
|
||||
|
||||
h += getCellHeight(getMeasuredWidth());
|
||||
if (isSingleCell) {
|
||||
k++;
|
||||
if (isSingleCell && k >= itemsCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +196,8 @@ public class FlickerLoadingView extends View {
|
|||
}
|
||||
}
|
||||
} else if (getViewType() == 3) {
|
||||
while (h < getMeasuredHeight()) {
|
||||
int k = 0;
|
||||
while (h <= getMeasuredHeight()) {
|
||||
rectF.set(AndroidUtilities.dp(12), h + AndroidUtilities.dp(8), AndroidUtilities.dp(52), h + AndroidUtilities.dp(48));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
@ -168,12 +217,14 @@ public class FlickerLoadingView extends View {
|
|||
}
|
||||
|
||||
h += getCellHeight(getMeasuredWidth());
|
||||
if (isSingleCell) {
|
||||
k++;
|
||||
if (isSingleCell && k >= itemsCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (getViewType() == 4) {
|
||||
while (h < getMeasuredHeight()) {
|
||||
int k = 0;
|
||||
while (h <= getMeasuredHeight()) {
|
||||
int radius = AndroidUtilities.dp(44) >> 1;
|
||||
canvas.drawCircle(checkRtl(AndroidUtilities.dp(12) + radius), h + AndroidUtilities.dp(6) + radius, radius, paint);
|
||||
|
||||
|
@ -192,12 +243,14 @@ public class FlickerLoadingView extends View {
|
|||
}
|
||||
|
||||
h += getCellHeight(getMeasuredWidth());
|
||||
if (isSingleCell) {
|
||||
k++;
|
||||
if (isSingleCell && k >= itemsCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (getViewType() == 5) {
|
||||
while (h < getMeasuredHeight()) {
|
||||
int k = 0;
|
||||
while (h <= getMeasuredHeight()) {
|
||||
rectF.set(AndroidUtilities.dp(10), h + AndroidUtilities.dp(11), AndroidUtilities.dp(62), h + AndroidUtilities.dp(11 + 52));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
@ -221,20 +274,22 @@ public class FlickerLoadingView extends View {
|
|||
}
|
||||
|
||||
h += getCellHeight(getMeasuredWidth());
|
||||
if (isSingleCell) {
|
||||
k++;
|
||||
if (isSingleCell && k >= itemsCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (getViewType() == 6) {
|
||||
while (h < getMeasuredHeight()) {
|
||||
} else if (getViewType() == 6 || getViewType() == USERS2_TYPE) {
|
||||
int k = 0;
|
||||
while (h <= getMeasuredHeight()) {
|
||||
int r = AndroidUtilities.dp(23);
|
||||
canvas.drawCircle(checkRtl(AndroidUtilities.dp(9) + r), h + (AndroidUtilities.dp(64) >> 1), r, paint);
|
||||
canvas.drawCircle(checkRtl(paddingLeft + AndroidUtilities.dp(9) + r), h + (AndroidUtilities.dp(64) >> 1), r, paint);
|
||||
|
||||
rectF.set(AndroidUtilities.dp(68), h + AndroidUtilities.dp(17), AndroidUtilities.dp(260), h + AndroidUtilities.dp(25));
|
||||
rectF.set(paddingLeft + AndroidUtilities.dp(68), h + AndroidUtilities.dp(17), paddingLeft + AndroidUtilities.dp(260), h + AndroidUtilities.dp(25));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
||||
rectF.set(AndroidUtilities.dp(68), h + AndroidUtilities.dp(39), AndroidUtilities.dp(140), h + AndroidUtilities.dp(47));
|
||||
rectF.set(paddingLeft + AndroidUtilities.dp(68), h + AndroidUtilities.dp(39), paddingLeft + AndroidUtilities.dp(140), h + AndroidUtilities.dp(47));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
||||
|
@ -245,7 +300,61 @@ public class FlickerLoadingView extends View {
|
|||
}
|
||||
|
||||
h += getCellHeight(getMeasuredWidth());
|
||||
if (isSingleCell) {
|
||||
k++;
|
||||
if (isSingleCell && k >= itemsCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (getViewType() == CALL_LOG_TYPE) {
|
||||
int k = 0;
|
||||
while (h <= getMeasuredHeight()) {
|
||||
int r = AndroidUtilities.dp(23);
|
||||
canvas.drawCircle(checkRtl(paddingLeft + AndroidUtilities.dp(11) + r), h + (AndroidUtilities.dp(64) >> 1), r, paint);
|
||||
|
||||
rectF.set(paddingLeft + AndroidUtilities.dp(68), h + AndroidUtilities.dp(17), paddingLeft + AndroidUtilities.dp(140), h + AndroidUtilities.dp(25));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
||||
rectF.set(paddingLeft + AndroidUtilities.dp(68), h + AndroidUtilities.dp(39), paddingLeft + AndroidUtilities.dp(260), h + AndroidUtilities.dp(47));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
||||
if (showDate) {
|
||||
rectF.set(getMeasuredWidth() - AndroidUtilities.dp(50), h + AndroidUtilities.dp(20), getMeasuredWidth() - AndroidUtilities.dp(12), h + AndroidUtilities.dp(28));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
}
|
||||
|
||||
h += getCellHeight(getMeasuredWidth());
|
||||
k++;
|
||||
if (isSingleCell && k >= itemsCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (getViewType() == INVITE_LINKS_TYPE) {
|
||||
int k = 0;
|
||||
while (h <= getMeasuredHeight()) {
|
||||
int childH = getCellHeight(getMeasuredWidth());
|
||||
int r = AndroidUtilities.dp(32) / 2;
|
||||
canvas.drawCircle(checkRtl(AndroidUtilities.dp(35)), h + (childH >> 1), r, paint);
|
||||
|
||||
rectF.set(AndroidUtilities.dp(72), h + AndroidUtilities.dp(16), AndroidUtilities.dp(268), h + AndroidUtilities.dp(24));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
||||
rectF.set(AndroidUtilities.dp(72), h + AndroidUtilities.dp(38), AndroidUtilities.dp(140), h + AndroidUtilities.dp(46));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
|
||||
if (showDate) {
|
||||
rectF.set(getMeasuredWidth() - AndroidUtilities.dp(50), h + AndroidUtilities.dp(16), getMeasuredWidth() - AndroidUtilities.dp(12), h + AndroidUtilities.dp(24));
|
||||
checkRtl(rectF);
|
||||
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
|
||||
}
|
||||
|
||||
h += getCellHeight(getMeasuredWidth());
|
||||
k++;
|
||||
if (isSingleCell && k >= itemsCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -289,7 +398,9 @@ public class FlickerLoadingView extends View {
|
|||
}
|
||||
|
||||
private int getCellHeight(int width) {
|
||||
if (getViewType() == DIALOG_TYPE) {
|
||||
if (getViewType() == DIALOG_CELL_TYPE) {
|
||||
return AndroidUtilities.dp((SharedConfig.useThreeLinesLayout ? 78 : 72) + 1);
|
||||
} else if (getViewType() == DIALOG_TYPE) {
|
||||
return AndroidUtilities.dp(78) + 1;
|
||||
} else if (getViewType() == PHOTOS_TYPE) {
|
||||
int photoWidth = (width - (AndroidUtilities.dp(2) * (getColumnsCount() - 1))) / getColumnsCount();
|
||||
|
@ -302,6 +413,12 @@ public class FlickerLoadingView extends View {
|
|||
return AndroidUtilities.dp(80);
|
||||
} else if (getViewType() == USERS_TYPE) {
|
||||
return AndroidUtilities.dp(64);
|
||||
} else if (getViewType() == INVITE_LINKS_TYPE) {
|
||||
return AndroidUtilities.dp(66);
|
||||
} else if (getViewType() == USERS2_TYPE) {
|
||||
return AndroidUtilities.dp(58);
|
||||
} else if (getViewType() == CALL_LOG_TYPE) {
|
||||
return AndroidUtilities.dp(61);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -317,4 +434,18 @@ public class FlickerLoadingView extends View {
|
|||
public void skipDrawItemsCount(int i) {
|
||||
skipDrawItemsCount = i;
|
||||
}
|
||||
|
||||
public void setPaddingTop(int t) {
|
||||
paddingTop = t;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setPaddingLeft(int paddingLeft) {
|
||||
this.paddingLeft = paddingLeft;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setItemsCount(int i) {
|
||||
this.itemsCount = i;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package org.telegram.ui.Components;
|
|||
|
||||
import android.text.TextPaint;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.UpdateAppearance;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.animation.Animator;
|
|||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
|
@ -43,6 +44,7 @@ import android.widget.TextView;
|
|||
import org.telegram.messenger.AccountInstance;
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
import org.telegram.messenger.ContactsController;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.LocationController;
|
||||
import org.telegram.messenger.MediaController;
|
||||
|
@ -73,7 +75,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
|
||||
private ImageView playButton;
|
||||
private PlayPauseDrawable playPauseDrawable;
|
||||
private TextView titleTextView;
|
||||
private AudioPlayerAlert.ClippingTextViewSwitcher titleTextView;
|
||||
private AudioPlayerAlert.ClippingTextViewSwitcher subtitleTextView;
|
||||
private AnimatorSet animatorSet;
|
||||
private BaseFragment fragment;
|
||||
|
@ -81,6 +83,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
private FrameLayout frameLayout;
|
||||
private View shadow;
|
||||
private View selector;
|
||||
private RLottieImageView importingImageView;
|
||||
private RLottieImageView muteButton;
|
||||
private RLottieDrawable muteDrawable;
|
||||
private ImageView closeButton;
|
||||
|
@ -90,6 +93,8 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
|
||||
private boolean isMuted;
|
||||
|
||||
private int currentProgress = -1;
|
||||
|
||||
private MessageObject lastMessageObject;
|
||||
private float topPadding;
|
||||
private boolean visible;
|
||||
|
@ -116,8 +121,9 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
};
|
||||
private int animationIndex = -1;
|
||||
|
||||
boolean checkCallAfterAnimation;
|
||||
boolean checkPlayerAfterAnimation;
|
||||
private boolean checkCallAfterAnimation;
|
||||
private boolean checkPlayerAfterAnimation;
|
||||
private boolean checkImportAfterAnimation;
|
||||
|
||||
@Override
|
||||
public void onAudioSettingsChanged() {
|
||||
|
@ -135,6 +141,10 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
}
|
||||
|
||||
public boolean drawOverlayed() {
|
||||
return currentStyle == 3;
|
||||
}
|
||||
|
||||
public interface FragmentContextViewDelegate {
|
||||
void onAnimation(boolean start, boolean show);
|
||||
}
|
||||
|
@ -191,13 +201,44 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
});
|
||||
|
||||
titleTextView = new TextView(context);
|
||||
titleTextView.setMaxLines(1);
|
||||
titleTextView.setLines(1);
|
||||
titleTextView.setSingleLine(true);
|
||||
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
titleTextView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
importingImageView = new RLottieImageView(context);
|
||||
importingImageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
importingImageView.setAutoRepeat(true);
|
||||
importingImageView.setAnimation(R.raw.import_progress, 30, 30);
|
||||
importingImageView.setBackground(Theme.createCircleDrawable(AndroidUtilities.dp(22), Theme.getColor(Theme.key_inappPlayerPlayPause)));
|
||||
addView(importingImageView, LayoutHelper.createFrame(22, 22, Gravity.TOP | Gravity.LEFT, 7, 7, 0, 0));
|
||||
|
||||
|
||||
titleTextView = new AudioPlayerAlert.ClippingTextViewSwitcher(context) {
|
||||
@Override
|
||||
protected TextView createTextView() {
|
||||
TextView textView = new TextView(context);
|
||||
textView.setMaxLines(1);
|
||||
textView.setLines(1);
|
||||
textView.setSingleLine(true);
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
|
||||
if (currentStyle == 0 || currentStyle == 2) {
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_inappPlayerTitle));
|
||||
textView.setTypeface(Typeface.DEFAULT);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
} else if (currentStyle == 4) {
|
||||
textView.setGravity(Gravity.TOP | Gravity.LEFT);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_inappPlayerPerformer));
|
||||
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
} else if (currentStyle == 1 || currentStyle == 3) {
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_returnToCallText));
|
||||
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
}
|
||||
return textView;
|
||||
}
|
||||
};
|
||||
addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 36, Gravity.LEFT | Gravity.TOP, 35, 0, 36, 0));
|
||||
|
||||
subtitleTextView = new AudioPlayerAlert.ClippingTextViewSwitcher(context) {
|
||||
|
@ -243,6 +284,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
} else {
|
||||
MediaController.getInstance().setPlaybackSpeed(isMusic, 1.8f);
|
||||
}
|
||||
playbackSpeedChanged(currentPlaybackSpeed <= 1);
|
||||
});
|
||||
updatePlaybackButton();
|
||||
}
|
||||
|
@ -291,7 +333,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (currentStyle == 3) {
|
||||
if (currentStyle == 3 || currentStyle == 1) {
|
||||
VoIPService service = VoIPService.getSharedInstance();
|
||||
if (service == null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(pressRunnable);
|
||||
|
@ -310,7 +352,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
scheduled = false;
|
||||
} else if (pressed) {
|
||||
isMuted = true;
|
||||
if (muteDrawable.setCustomEndFrame(isMuted ? 15 : 29)) {
|
||||
if (muteDrawable.setCustomEndFrame(15)) {
|
||||
if (isMuted) {
|
||||
muteDrawable.setCurrentFrame(0);
|
||||
} else {
|
||||
|
@ -356,12 +398,14 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
if (voIPService == null) {
|
||||
return;
|
||||
}
|
||||
ChatObject.Call call = voIPService.groupCall;
|
||||
AccountInstance accountInstance = AccountInstance.getInstance(voIPService.getAccount());
|
||||
TLRPC.Chat chat = voIPService.getChat();
|
||||
TLRPC.TL_groupCallParticipant participant = call.participants.get(accountInstance.getUserConfig().getClientUserId());
|
||||
if (participant != null && !participant.can_self_unmute && participant.muted && !ChatObject.canManageCalls(chat)) {
|
||||
return;
|
||||
if (voIPService.groupCall != null) {
|
||||
AccountInstance accountInstance = AccountInstance.getInstance(voIPService.getAccount());
|
||||
ChatObject.Call call = voIPService.groupCall;
|
||||
TLRPC.Chat chat = voIPService.getChat();
|
||||
TLRPC.TL_groupCallParticipant participant = call.participants.get(accountInstance.getUserConfig().getClientUserId());
|
||||
if (participant != null && !participant.can_self_unmute && participant.muted && !ChatObject.canManageCalls(chat)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
isMuted = !voIPService.isMicMute();
|
||||
|
@ -483,12 +527,9 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
fragment.showDialog(new SharingLocationsAlert(getContext(), this::openSharingLocation));
|
||||
}
|
||||
} else if (currentStyle == 3) {
|
||||
// long d = Theme.getFragmentContextViewWavesDrawable().getRippleFinishedDelay();
|
||||
// AndroidUtilities.runOnUIThread(() -> {
|
||||
if (VoIPService.getSharedInstance() != null && getContext() instanceof LaunchActivity) {
|
||||
GroupCallActivity.create((LaunchActivity) getContext(), AccountInstance.getInstance(VoIPService.getSharedInstance().getAccount()));
|
||||
}
|
||||
// }, d);
|
||||
if (VoIPService.getSharedInstance() != null && getContext() instanceof LaunchActivity) {
|
||||
GroupCallActivity.create((LaunchActivity) getContext(), AccountInstance.getInstance(VoIPService.getSharedInstance().getAccount()));
|
||||
}
|
||||
} else if (currentStyle == 4) {
|
||||
if (fragment.getParentActivity() == null) {
|
||||
return;
|
||||
|
@ -499,6 +540,11 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
return;
|
||||
}
|
||||
VoIPHelper.startCall(chatActivity.getMessagesController().getChat(call.chatId), false, fragment.getParentActivity());
|
||||
} else if (currentStyle == 5) {
|
||||
ImportingAlert importingAlert = new ImportingAlert(getContext(), (ChatActivity) fragment);
|
||||
importingAlert.setOnHideListener(dialog -> checkImport(false));
|
||||
fragment.showDialog(importingAlert);
|
||||
checkImport(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -562,7 +608,9 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
} else {
|
||||
if (VoIPService.getSharedInstance() != null && !VoIPService.getSharedInstance().isHangingUp() && VoIPService.getSharedInstance().getCallState() != VoIPService.STATE_WAITING_INCOMING) {
|
||||
show = true;
|
||||
} else if (fragment instanceof ChatActivity && ((ChatActivity) fragment).getGroupCall() != null) {
|
||||
} else if (fragment instanceof ChatActivity && fragment.getSendMessagesHelper().getImportingHistory(((ChatActivity) fragment).getDialogId()) != null && !isPlayingVoice()) {
|
||||
show = true;
|
||||
} else if (fragment instanceof ChatActivity && ((ChatActivity) fragment).getGroupCall() != null && !GroupCallPip.isShowing() && !isPlayingVoice()) {
|
||||
show = true;
|
||||
} else {
|
||||
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
|
||||
|
@ -589,11 +637,15 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
}
|
||||
|
||||
protected void playbackSpeedChanged(boolean enabled) {
|
||||
|
||||
}
|
||||
|
||||
private void updateStyle(int style) {
|
||||
if (currentStyle == style) {
|
||||
return;
|
||||
}
|
||||
if (currentStyle == 3) {
|
||||
if (currentStyle == 3 || currentStyle == 1) {
|
||||
Theme.getFragmentContextViewWavesDrawable().removeParent(this);
|
||||
if (VoIPService.getSharedInstance() != null) {
|
||||
VoIPService.getSharedInstance().unregisterStateListener(this);
|
||||
|
@ -601,7 +653,6 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
currentStyle = style;
|
||||
|
||||
|
||||
if (avatars != null) {
|
||||
avatars.setStyle(currentStyle);
|
||||
avatars.setLayoutParams(LayoutHelper.createFrame(108, getStyleHeight(), Gravity.LEFT | Gravity.TOP));
|
||||
|
@ -613,21 +664,59 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
updatePaddings();
|
||||
setTopPadding(AndroidUtilities.dp2(getStyleHeight()));
|
||||
}
|
||||
if (style == 0 || style == 2) {
|
||||
if (style == 5) {
|
||||
selector.setBackground(Theme.getSelectorDrawable(false));
|
||||
frameLayout.setBackgroundColor(Theme.getColor(Theme.key_inappPlayerBackground));
|
||||
frameLayout.setTag(Theme.key_inappPlayerBackground);
|
||||
titleTextView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
titleTextView.setTextColor(Theme.getColor(Theme.key_inappPlayerTitle));
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? titleTextView.getTextView() : titleTextView.getNextTextView();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_inappPlayerTitle));
|
||||
textView.setTypeface(Typeface.DEFAULT);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
}
|
||||
titleTextView.setTag(Theme.key_inappPlayerTitle);
|
||||
subtitleTextView.setVisibility(GONE);
|
||||
joinButton.setVisibility(GONE);
|
||||
closeButton.setVisibility(GONE);
|
||||
playButton.setVisibility(GONE);
|
||||
muteButton.setVisibility(GONE);
|
||||
avatars.setVisibility(GONE);
|
||||
importingImageView.setVisibility(VISIBLE);
|
||||
importingImageView.playAnimation();
|
||||
closeButton.setContentDescription(LocaleController.getString("AccDescrClosePlayer", R.string.AccDescrClosePlayer));
|
||||
if (playbackSpeedButton != null) {
|
||||
playbackSpeedButton.setVisibility(GONE);
|
||||
}
|
||||
titleTextView.setLayoutParams(LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 36, Gravity.LEFT | Gravity.TOP, 35, 0, 36, 0));
|
||||
} else if (style == 0 || style == 2) {
|
||||
selector.setBackground(Theme.getSelectorDrawable(false));
|
||||
frameLayout.setBackgroundColor(Theme.getColor(Theme.key_inappPlayerBackground));
|
||||
frameLayout.setTag(Theme.key_inappPlayerBackground);
|
||||
|
||||
subtitleTextView.setVisibility(GONE);
|
||||
joinButton.setVisibility(GONE);
|
||||
closeButton.setVisibility(VISIBLE);
|
||||
playButton.setVisibility(VISIBLE);
|
||||
muteButton.setVisibility(GONE);
|
||||
importingImageView.setVisibility(GONE);
|
||||
importingImageView.stopAnimation();
|
||||
avatars.setVisibility(GONE);
|
||||
titleTextView.setTypeface(Typeface.DEFAULT);
|
||||
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? titleTextView.getTextView() : titleTextView.getNextTextView();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_inappPlayerTitle));
|
||||
textView.setTypeface(Typeface.DEFAULT);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
}
|
||||
titleTextView.setTag(Theme.key_inappPlayerTitle);
|
||||
if (style == 0) {
|
||||
playButton.setLayoutParams(LayoutHelper.createFrame(36, 36, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 0));
|
||||
titleTextView.setLayoutParams(LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 36, Gravity.LEFT | Gravity.TOP, 35, 0, 36, 0));
|
||||
|
@ -649,13 +738,22 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
subtitleTextView.setVisibility(VISIBLE);
|
||||
joinButton.setVisibility(VISIBLE);
|
||||
|
||||
titleTextView.setTextColor(Theme.getColor(Theme.key_inappPlayerPerformer));
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? titleTextView.getTextView() : titleTextView.getNextTextView();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
textView.setGravity(Gravity.TOP | Gravity.LEFT);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_inappPlayerPerformer));
|
||||
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
}
|
||||
titleTextView.setTag(Theme.key_inappPlayerPerformer);
|
||||
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
titleTextView.setPadding(0, 0, 0, 0);
|
||||
titleTextView.setText(LocaleController.getString("VoipGroupVoiceChat", R.string.VoipGroupVoiceChat));
|
||||
titleTextView.setGravity(Gravity.TOP | Gravity.LEFT);
|
||||
titleTextView.setText(LocaleController.getString("VoipGroupVoiceChat", R.string.VoipGroupVoiceChat), false);
|
||||
|
||||
importingImageView.setVisibility(GONE);
|
||||
importingImageView.stopAnimation();
|
||||
|
||||
avatars.setVisibility(VISIBLE);
|
||||
updateAvatars(false);
|
||||
|
@ -667,37 +765,42 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
} else if (style == 1 || style == 3) {
|
||||
selector.setBackground(null);
|
||||
updateCallTitle();
|
||||
avatars.setVisibility(VISIBLE);
|
||||
if (style == 3) {
|
||||
updateGroupCallTitle();
|
||||
muteButton.setVisibility(VISIBLE);
|
||||
avatars.setVisibility(VISIBLE);
|
||||
updateAvatars(false);
|
||||
isMuted = VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().isMicMute();
|
||||
muteDrawable.setCustomEndFrame(isMuted ? 15 : 29);
|
||||
muteDrawable.setCurrentFrame(muteDrawable.getCustomEndFrame() - 1, false, true);
|
||||
muteButton.invalidate();
|
||||
frameLayout.setBackground(null);
|
||||
Theme.getFragmentContextViewWavesDrawable().addParent(this);
|
||||
if (VoIPService.getSharedInstance() != null) {
|
||||
VoIPService.getSharedInstance().registerStateListener(this);
|
||||
}
|
||||
invalidate();
|
||||
} else {
|
||||
frameLayout.setTag(Theme.key_returnToCallBackground);
|
||||
titleTextView.setText(LocaleController.getString("ReturnToCall", R.string.ReturnToCall));
|
||||
muteButton.setVisibility(GONE);
|
||||
avatars.setVisibility(GONE);
|
||||
frameLayout.setBackgroundColor(Theme.getColor(Theme.key_returnToCallBackground));
|
||||
}
|
||||
titleTextView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
titleTextView.setTextColor(Theme.getColor(Theme.key_returnToCallText));
|
||||
updateAvatars(false);
|
||||
muteButton.setVisibility(VISIBLE);
|
||||
isMuted = VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().isMicMute();
|
||||
muteDrawable.setCustomEndFrame(isMuted ? 15 : 29);
|
||||
muteDrawable.setCurrentFrame(muteDrawable.getCustomEndFrame() - 1, false, true);
|
||||
muteButton.invalidate();
|
||||
frameLayout.setBackground(null);
|
||||
importingImageView.setVisibility(GONE);
|
||||
importingImageView.stopAnimation();
|
||||
Theme.getFragmentContextViewWavesDrawable().addParent(this);
|
||||
invalidate();
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? titleTextView.getTextView() : titleTextView.getNextTextView();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_returnToCallText));
|
||||
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
}
|
||||
|
||||
titleTextView.setTag(Theme.key_returnToCallText);
|
||||
closeButton.setVisibility(GONE);
|
||||
playButton.setVisibility(GONE);
|
||||
subtitleTextView.setVisibility(GONE);
|
||||
joinButton.setVisibility(GONE);
|
||||
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
|
||||
titleTextView.setLayoutParams(LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 0, 0, 0, 2));
|
||||
titleTextView.setPadding(AndroidUtilities.dp(112), 0, AndroidUtilities.dp(112), 0);
|
||||
if (playbackSpeedButton != null) {
|
||||
|
@ -726,6 +829,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
NotificationCenter.getInstance(a).removeObserver(this, NotificationCenter.messagePlayingDidStart);
|
||||
NotificationCenter.getInstance(a).removeObserver(this, NotificationCenter.groupCallUpdated);
|
||||
NotificationCenter.getInstance(a).removeObserver(this, NotificationCenter.groupCallTypingsUpdated);
|
||||
NotificationCenter.getInstance(a).removeObserver(this, NotificationCenter.historyImportProgressChanged);
|
||||
}
|
||||
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.messagePlayingSpeedChanged);
|
||||
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didStartedCall);
|
||||
|
@ -735,7 +839,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.groupCallVisibilityChanged);
|
||||
}
|
||||
|
||||
if (currentStyle == 3) {
|
||||
if (currentStyle == 3 || currentStyle == 1) {
|
||||
Theme.getFragmentContextViewWavesDrawable().removeParent(this);
|
||||
}
|
||||
if (VoIPService.getSharedInstance() != null) {
|
||||
|
@ -761,6 +865,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
NotificationCenter.getInstance(a).addObserver(this, NotificationCenter.messagePlayingDidStart);
|
||||
NotificationCenter.getInstance(a).addObserver(this, NotificationCenter.groupCallUpdated);
|
||||
NotificationCenter.getInstance(a).addObserver(this, NotificationCenter.groupCallTypingsUpdated);
|
||||
NotificationCenter.getInstance(a).addObserver(this, NotificationCenter.historyImportProgressChanged);
|
||||
}
|
||||
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.messagePlayingSpeedChanged);
|
||||
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.didStartedCall);
|
||||
|
@ -774,6 +879,8 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
|
||||
if (VoIPService.getSharedInstance() != null && !VoIPService.getSharedInstance().isHangingUp() && VoIPService.getSharedInstance().getCallState() != VoIPService.STATE_WAITING_INCOMING && !GroupCallPip.isShowing()) {
|
||||
checkCall(true);
|
||||
} else if (fragment instanceof ChatActivity && fragment.getSendMessagesHelper().getImportingHistory(((ChatActivity) fragment).getDialogId()) != null && !isPlayingVoice()) {
|
||||
checkImport(true);
|
||||
} else if (fragment instanceof ChatActivity && ((ChatActivity) fragment).getGroupCall() != null && !GroupCallPip.isShowing() && !isPlayingVoice()) {
|
||||
checkCall(true);
|
||||
} else {
|
||||
|
@ -782,7 +889,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
}
|
||||
|
||||
if (currentStyle == 3) {
|
||||
if (currentStyle == 3 || currentStyle == 1) {
|
||||
Theme.getFragmentContextViewWavesDrawable().addParent(this);
|
||||
if (VoIPService.getSharedInstance() != null) {
|
||||
VoIPService.getSharedInstance().registerStateListener(this);
|
||||
|
@ -822,7 +929,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
}
|
||||
} else if (id == NotificationCenter.messagePlayingDidStart || id == NotificationCenter.messagePlayingPlayStateChanged || id == NotificationCenter.messagePlayingDidReset || id == NotificationCenter.didEndCall) {
|
||||
if (currentStyle == 3 || currentStyle == 4) {
|
||||
if (currentStyle == 1 || currentStyle == 3 || currentStyle == 4) {
|
||||
checkCall(false);
|
||||
}
|
||||
checkPlayer(false);
|
||||
|
@ -853,13 +960,18 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
ChatObject.Call call = ((ChatActivity) fragment).getGroupCall();
|
||||
if (call != null) {
|
||||
if (call.call.participants_count == 0) {
|
||||
subtitleTextView.setText(LocaleController.getString("MembersTalkingNobody", R.string.MembersTalkingNobody));
|
||||
subtitleTextView.setText(LocaleController.getString("MembersTalkingNobody", R.string.MembersTalkingNobody), false);
|
||||
} else {
|
||||
subtitleTextView.setText(LocaleController.formatPluralString("Participants", call.call.participants_count));
|
||||
subtitleTextView.setText(LocaleController.formatPluralString("Participants", call.call.participants_count), false);
|
||||
}
|
||||
}
|
||||
updateAvatars(true);
|
||||
}
|
||||
} else if (id == NotificationCenter.historyImportProgressChanged) {
|
||||
if (currentStyle == 1 || currentStyle == 3 || currentStyle == 4) {
|
||||
checkCall(false);
|
||||
}
|
||||
checkImport(false);
|
||||
} else if (id == NotificationCenter.messagePlayingSpeedChanged) {
|
||||
updatePlaybackButton();
|
||||
} else if (id == NotificationCenter.webRtcMicAmplitudeEvent) {
|
||||
|
@ -994,10 +1106,17 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
String fullString = String.format(str, liveLocation, param);
|
||||
int start = fullString.indexOf(liveLocation);
|
||||
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(fullString);
|
||||
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? titleTextView.getTextView() : titleTextView.getNextTextView();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
}
|
||||
|
||||
TypefaceSpan span = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, Theme.getColor(Theme.key_inappPlayerPerformer));
|
||||
stringBuilder.setSpan(span, start, start + liveLocation.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
titleTextView.setText(stringBuilder);
|
||||
titleTextView.setText(stringBuilder, false);
|
||||
} else {
|
||||
checkLocationRunnable.run();
|
||||
checkLocationString();
|
||||
|
@ -1072,16 +1191,22 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
lastString = fullString;
|
||||
int start = fullString.indexOf(liveLocation);
|
||||
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(fullString);
|
||||
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? titleTextView.getTextView() : titleTextView.getNextTextView();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
}
|
||||
if (start >= 0) {
|
||||
TypefaceSpan span = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, Theme.getColor(Theme.key_inappPlayerPerformer));
|
||||
stringBuilder.setSpan(span, start, start + liveLocation.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
}
|
||||
titleTextView.setText(stringBuilder);
|
||||
titleTextView.setText(stringBuilder, false);
|
||||
}
|
||||
|
||||
private void checkPlayer(boolean create) {
|
||||
if (visible && (currentStyle == 3 || currentStyle == 4 && !isPlayingVoice())) {
|
||||
if (visible && (currentStyle == 1 || currentStyle == 3 || (currentStyle == 4 || currentStyle == 5) && !isPlayingVoice())) {
|
||||
return;
|
||||
}
|
||||
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
|
||||
|
@ -1091,6 +1216,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
create = true;
|
||||
}
|
||||
}
|
||||
boolean wasVisible = visible;
|
||||
if (messageObject == null || messageObject.getId() == 0 || messageObject.isVideo()) {
|
||||
lastMessageObject = null;
|
||||
boolean callAvailable = supportsCalls && VoIPService.getSharedInstance() != null && !VoIPService.getSharedInstance().isHangingUp() && VoIPService.getSharedInstance().getCallState() != VoIPService.STATE_WAITING_INCOMING && !GroupCallPip.isShowing();
|
||||
|
@ -1134,9 +1260,12 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
checkCall(false);
|
||||
} else if (checkPlayerAfterAnimation) {
|
||||
checkPlayer(false);
|
||||
} else if (checkImportAfterAnimation) {
|
||||
checkImport(false);
|
||||
}
|
||||
checkCallAfterAnimation = false;
|
||||
checkPlayerAfterAnimation = false;
|
||||
checkImportAfterAnimation = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1191,9 +1320,12 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
checkCall(false);
|
||||
} else if (checkPlayerAfterAnimation) {
|
||||
checkPlayer(false);
|
||||
} else if (checkImportAfterAnimation) {
|
||||
checkImport(false);
|
||||
}
|
||||
checkCallAfterAnimation = false;
|
||||
checkPlayerAfterAnimation = false;
|
||||
checkImportAfterAnimation = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1220,7 +1352,15 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
titleTextView.setPadding(0, 0, AndroidUtilities.dp(44), 0);
|
||||
stringBuilder = new SpannableStringBuilder(String.format("%s %s", messageObject.getMusicAuthor(), messageObject.getMusicTitle()));
|
||||
titleTextView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? titleTextView.getTextView() : titleTextView.getNextTextView();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
textView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
|
||||
}
|
||||
|
||||
updatePlaybackButton();
|
||||
} else {
|
||||
isMusic = true;
|
||||
|
@ -1239,46 +1379,41 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
titleTextView.setPadding(0, 0, 0, 0);
|
||||
}
|
||||
stringBuilder = new SpannableStringBuilder(String.format("%s - %s", messageObject.getMusicAuthor(), messageObject.getMusicTitle()));
|
||||
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
TextView textView = i == 0 ? titleTextView.getTextView() : titleTextView.getNextTextView();
|
||||
if (textView == null) {
|
||||
continue;
|
||||
}
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
}
|
||||
}
|
||||
TypefaceSpan span = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, Theme.getColor(Theme.key_inappPlayerPerformer));
|
||||
stringBuilder.setSpan(span, 0, messageObject.getMusicAuthor().length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
titleTextView.setText(stringBuilder);
|
||||
titleTextView.setText(stringBuilder, !create && wasVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPlayingVoice() {
|
||||
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
|
||||
return messageObject != null && messageObject.isVoice();
|
||||
}
|
||||
|
||||
public void checkCall(boolean create) {
|
||||
public void checkImport(boolean create) {
|
||||
if (!(fragment instanceof ChatActivity) || visible && (currentStyle == 1 || currentStyle == 3)) {
|
||||
return;
|
||||
}
|
||||
ChatActivity chatActivity = (ChatActivity) fragment;
|
||||
SendMessagesHelper.ImportingHistory importingHistory = chatActivity.getSendMessagesHelper().getImportingHistory(chatActivity.getDialogId());
|
||||
View fragmentView = fragment.getFragmentView();
|
||||
if (!create && fragmentView != null) {
|
||||
if (fragmentView.getParent() == null || ((View) fragmentView.getParent()).getVisibility() != VISIBLE) {
|
||||
create = true;
|
||||
}
|
||||
}
|
||||
boolean callAvailable;
|
||||
boolean groupActive;
|
||||
if (GroupCallPip.isShowing()) {
|
||||
callAvailable = false;
|
||||
groupActive = false;
|
||||
} else {
|
||||
callAvailable = !GroupCallActivity.groupCallUiVisible && supportsCalls && VoIPService.getSharedInstance() != null && !VoIPService.getSharedInstance().isHangingUp();
|
||||
if (VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().groupCall != null && VoIPService.getSharedInstance().groupCall.call instanceof TLRPC.TL_groupCallDiscarded) {
|
||||
callAvailable = false;
|
||||
}
|
||||
groupActive = false;
|
||||
if (!isPlayingVoice() && !GroupCallActivity.groupCallUiVisible && supportsCalls && !callAvailable && fragment instanceof ChatActivity && ((ChatActivity) fragment).getGroupCall() != null) {
|
||||
callAvailable = true;
|
||||
groupActive = true;
|
||||
}
|
||||
|
||||
Dialog dialog = chatActivity.getVisibleDialog();
|
||||
if ((isPlayingVoice() || chatActivity.shouldShowImport() || dialog instanceof ImportingAlert && !((ImportingAlert) dialog).isDismissed()) && importingHistory != null) {
|
||||
importingHistory = null;
|
||||
}
|
||||
|
||||
if (!callAvailable) {
|
||||
if (visible && (create && currentStyle == -1 || currentStyle == 4 || currentStyle == 3)) {
|
||||
if (importingHistory == null) {
|
||||
if (visible && (create && currentStyle == -1 || currentStyle == 5)) {
|
||||
visible = false;
|
||||
if (create) {
|
||||
if (getVisibility() != GONE) {
|
||||
|
@ -1307,15 +1442,165 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
checkCall(false);
|
||||
} else if (checkPlayerAfterAnimation) {
|
||||
checkPlayer(false);
|
||||
} else if (checkImportAfterAnimation) {
|
||||
checkImport(false);
|
||||
}
|
||||
checkCallAfterAnimation = false;
|
||||
checkPlayerAfterAnimation = false;
|
||||
checkImportAfterAnimation = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
animatorSet.start();
|
||||
}
|
||||
} else if (currentStyle == -1 || currentStyle == 4 || currentStyle == 3) {
|
||||
} else if (currentStyle == -1 || currentStyle == 5) {
|
||||
visible = false;
|
||||
setVisibility(GONE);
|
||||
}
|
||||
} else {
|
||||
if (currentStyle != 5 && animatorSet != null && !create) {
|
||||
checkImportAfterAnimation = true;
|
||||
return;
|
||||
}
|
||||
int prevStyle = currentStyle;
|
||||
updateStyle(5);
|
||||
if (create && topPadding == 0) {
|
||||
updatePaddings();
|
||||
setTopPadding(AndroidUtilities.dp2(getStyleHeight()));
|
||||
if (delegate != null) {
|
||||
delegate.onAnimation(true, true);
|
||||
delegate.onAnimation(false, true);
|
||||
}
|
||||
}
|
||||
if (!visible) {
|
||||
if (!create) {
|
||||
if (animatorSet != null) {
|
||||
animatorSet.cancel();
|
||||
animatorSet = null;
|
||||
}
|
||||
animationIndex = NotificationCenter.getInstance(account).setAnimationInProgress(animationIndex, null);
|
||||
animatorSet = new AnimatorSet();
|
||||
if (additionalContextView != null && additionalContextView.getVisibility() == VISIBLE) {
|
||||
((LayoutParams) getLayoutParams()).topMargin = -AndroidUtilities.dp(getStyleHeight() + additionalContextView.getStyleHeight());
|
||||
} else {
|
||||
((LayoutParams) getLayoutParams()).topMargin = -AndroidUtilities.dp(getStyleHeight());
|
||||
}
|
||||
if (delegate != null) {
|
||||
delegate.onAnimation(true, true);
|
||||
}
|
||||
animatorSet.playTogether(ObjectAnimator.ofFloat(this, "topPadding", AndroidUtilities.dp2(getStyleHeight())));
|
||||
animatorSet.setDuration(200);
|
||||
animatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
NotificationCenter.getInstance(account).onAnimationFinish(animationIndex);
|
||||
if (animatorSet != null && animatorSet.equals(animation)) {
|
||||
if (delegate != null) {
|
||||
delegate.onAnimation(false, true);
|
||||
}
|
||||
animatorSet = null;
|
||||
if (checkCallAfterAnimation) {
|
||||
checkCall(false);
|
||||
} else if (checkPlayerAfterAnimation) {
|
||||
checkPlayer(false);
|
||||
} else if (checkImportAfterAnimation) {
|
||||
checkImport(false);
|
||||
}
|
||||
checkCallAfterAnimation = false;
|
||||
checkPlayerAfterAnimation = false;
|
||||
checkImportAfterAnimation = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
animatorSet.start();
|
||||
}
|
||||
visible = true;
|
||||
setVisibility(VISIBLE);
|
||||
}
|
||||
if (currentProgress != importingHistory.uploadProgress) {
|
||||
currentProgress = importingHistory.uploadProgress;
|
||||
titleTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("ImportUploading", R.string.ImportUploading, importingHistory.uploadProgress)), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPlayingVoice() {
|
||||
MessageObject messageObject = MediaController.getInstance().getPlayingMessageObject();
|
||||
return messageObject != null && messageObject.isVoice();
|
||||
}
|
||||
|
||||
public void checkCall(boolean create) {
|
||||
if (visible && currentStyle == 5 && (VoIPService.getSharedInstance() == null || VoIPService.getSharedInstance().isHangingUp())) {
|
||||
return;
|
||||
}
|
||||
View fragmentView = fragment.getFragmentView();
|
||||
if (!create && fragmentView != null) {
|
||||
if (fragmentView.getParent() == null || ((View) fragmentView.getParent()).getVisibility() != VISIBLE) {
|
||||
create = true;
|
||||
}
|
||||
}
|
||||
boolean callAvailable;
|
||||
boolean groupActive;
|
||||
if (GroupCallPip.isShowing()) {
|
||||
callAvailable = false;
|
||||
groupActive = false;
|
||||
} else {
|
||||
callAvailable = !GroupCallActivity.groupCallUiVisible && supportsCalls && VoIPService.getSharedInstance() != null && !VoIPService.getSharedInstance().isHangingUp();
|
||||
if (VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().groupCall != null && VoIPService.getSharedInstance().groupCall.call instanceof TLRPC.TL_groupCallDiscarded) {
|
||||
callAvailable = false;
|
||||
}
|
||||
groupActive = false;
|
||||
if (!isPlayingVoice() && !GroupCallActivity.groupCallUiVisible && supportsCalls && !callAvailable && fragment instanceof ChatActivity) {
|
||||
ChatObject.Call call = ((ChatActivity) fragment).getGroupCall();
|
||||
if (call != null && call.call.participants_count > 0) {
|
||||
callAvailable = true;
|
||||
groupActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!callAvailable) {
|
||||
if (visible && (create && currentStyle == -1 || currentStyle == 4 || currentStyle == 3 || currentStyle == 1)) {
|
||||
visible = false;
|
||||
if (create) {
|
||||
if (getVisibility() != GONE) {
|
||||
setVisibility(GONE);
|
||||
}
|
||||
setTopPadding(0);
|
||||
} else {
|
||||
if (animatorSet != null) {
|
||||
animatorSet.cancel();
|
||||
animatorSet = null;
|
||||
}
|
||||
final int currentAccount = account;
|
||||
animationIndex = NotificationCenter.getInstance(currentAccount).setAnimationInProgress(animationIndex, null);
|
||||
animatorSet = new AnimatorSet();
|
||||
animatorSet.playTogether(ObjectAnimator.ofFloat(this, "topPadding", 0));
|
||||
animatorSet.setDuration(220);
|
||||
animatorSet.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
animatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
NotificationCenter.getInstance(currentAccount).onAnimationFinish(animationIndex);
|
||||
if (animatorSet != null && animatorSet.equals(animation)) {
|
||||
setVisibility(GONE);
|
||||
animatorSet = null;
|
||||
if (checkCallAfterAnimation) {
|
||||
checkCall(false);
|
||||
} else if (checkPlayerAfterAnimation) {
|
||||
checkPlayer(false);
|
||||
} else if (checkImportAfterAnimation) {
|
||||
checkImport(false);
|
||||
}
|
||||
checkCallAfterAnimation = false;
|
||||
checkPlayerAfterAnimation = false;
|
||||
checkImportAfterAnimation = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
animatorSet.start();
|
||||
}
|
||||
} else if (currentStyle == -1 || currentStyle == 4 || currentStyle == 3 || currentStyle == 1) {
|
||||
visible = false;
|
||||
setVisibility(GONE);
|
||||
}
|
||||
|
@ -1364,9 +1649,9 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
ChatObject.Call call = ((ChatActivity) fragment).getGroupCall();
|
||||
|
||||
if (call.call.participants_count == 0) {
|
||||
subtitleTextView.setText(LocaleController.getString("MembersTalkingNobody", R.string.MembersTalkingNobody));
|
||||
subtitleTextView.setText(LocaleController.getString("MembersTalkingNobody", R.string.MembersTalkingNobody), false);
|
||||
} else {
|
||||
subtitleTextView.setText(LocaleController.formatPluralString("Participants", call.call.participants_count));
|
||||
subtitleTextView.setText(LocaleController.formatPluralString("Participants", call.call.participants_count), false);
|
||||
}
|
||||
|
||||
updateAvatars(avatars.wasDraw && updateAnimated);
|
||||
|
@ -1375,6 +1660,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
updateAvatars(currentStyle == 3);
|
||||
updateStyle(3);
|
||||
} else {
|
||||
updateAvatars(currentStyle == 1);
|
||||
updateStyle(1);
|
||||
}
|
||||
}
|
||||
|
@ -1406,9 +1692,12 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
checkCall(false);
|
||||
} else if (checkPlayerAfterAnimation) {
|
||||
checkPlayer(false);
|
||||
} else if (checkImportAfterAnimation) {
|
||||
checkImport(false);
|
||||
}
|
||||
checkCallAfterAnimation = false;
|
||||
checkPlayerAfterAnimation = false;
|
||||
checkImportAfterAnimation = false;
|
||||
}
|
||||
});
|
||||
animatorSet.start();
|
||||
|
@ -1430,6 +1719,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
}
|
||||
}
|
||||
ChatObject.Call call;
|
||||
TLRPC.User userCall;
|
||||
if (avatars.transitionProgressAnimator == null) {
|
||||
int currentAccount;
|
||||
if (currentStyle == 4) {
|
||||
|
@ -1441,12 +1731,15 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
call = null;
|
||||
currentAccount = account;
|
||||
}
|
||||
userCall = null;
|
||||
} else {
|
||||
if (VoIPService.getSharedInstance() != null) {
|
||||
call = VoIPService.getSharedInstance().groupCall;
|
||||
userCall = fragment instanceof ChatActivity ? null : VoIPService.getSharedInstance().getUser();
|
||||
currentAccount = VoIPService.getSharedInstance().getAccount();
|
||||
} else {
|
||||
call = null;
|
||||
userCall = null;
|
||||
currentAccount = account;
|
||||
}
|
||||
}
|
||||
|
@ -1458,13 +1751,17 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
avatars.setObject(a, currentAccount, null);
|
||||
}
|
||||
}
|
||||
avatars.commitTransition(animated);
|
||||
} else if (userCall != null) {
|
||||
avatars.setObject(0, currentAccount, userCall);
|
||||
for (int a = 1; a < 3; a++) {
|
||||
avatars.setObject(a, currentAccount, null);
|
||||
}
|
||||
} else {
|
||||
for (int a = 0; a < 3; a++) {
|
||||
avatars.setObject(a, currentAccount, null);
|
||||
}
|
||||
avatars.commitTransition(animated);
|
||||
}
|
||||
avatars.commitTransition(animated);
|
||||
|
||||
if (currentStyle == 4 && call != null) {
|
||||
int N = Math.min(3, call.sortedParticipants.size());
|
||||
|
@ -1510,7 +1807,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
return;
|
||||
}
|
||||
boolean clipped = false;
|
||||
if (currentStyle == 3 && drawOverlay) {
|
||||
if ((currentStyle == 3 || currentStyle == 1) && drawOverlay) {
|
||||
Theme.getFragmentContextViewWavesDrawable().updateState(wasDraw);
|
||||
float progress = topPadding / AndroidUtilities.dp((getStyleHeight()));
|
||||
|
||||
|
@ -1547,15 +1844,15 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
@Override
|
||||
public void invalidate() {
|
||||
super.invalidate();
|
||||
if (currentStyle == 3) {
|
||||
if (currentStyle == 3 || currentStyle == 1) {
|
||||
if (getParent() != null) {
|
||||
((View) getParent()).invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentStyle() {
|
||||
return currentStyle;
|
||||
public boolean isCallStyle() {
|
||||
return currentStyle == 3 || currentStyle == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1584,35 +1881,29 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
|
|||
|
||||
@Override
|
||||
public void onStateChanged(int state) {
|
||||
updateGroupCallTitle();
|
||||
updateCallTitle();
|
||||
}
|
||||
|
||||
private void updateGroupCallTitle() {
|
||||
private void updateCallTitle() {
|
||||
VoIPService service = VoIPService.getSharedInstance();
|
||||
if (service != null && currentStyle == 3) {
|
||||
if (service != null && (currentStyle == 1 || currentStyle == 3)) {
|
||||
int currentCallState = service.getCallState();
|
||||
if (currentCallState == VoIPService.STATE_WAIT_INIT || currentCallState == VoIPService.STATE_WAIT_INIT_ACK || currentCallState == VoIPService.STATE_CREATING || currentCallState == VoIPService.STATE_RECONNECTING) {
|
||||
titleTextView.setText(LocaleController.getString("VoipGroupConnecting", R.string. VoipGroupConnecting));
|
||||
titleTextView.setText(LocaleController.getString("VoipGroupConnecting", R.string. VoipGroupConnecting), false);
|
||||
} else if (service.getChat() != null) {
|
||||
if (fragment instanceof ChatActivity && ((ChatActivity) fragment).getCurrentChat() != null && ((ChatActivity) fragment).getCurrentChat().id == service.getChat().id) {
|
||||
titleTextView.setText(LocaleController.getString("VoipGroupViewVoiceChat", R.string.VoipGroupViewVoiceChat));
|
||||
titleTextView.setText(LocaleController.getString("VoipGroupViewVoiceChat", R.string.VoipGroupViewVoiceChat), false);
|
||||
} else {
|
||||
titleTextView.setText(service.getChat().title);
|
||||
titleTextView.setText(service.getChat().title, false);
|
||||
}
|
||||
} else if (service.getUser() != null) {
|
||||
TLRPC.User user = service.getUser();
|
||||
if (fragment instanceof ChatActivity && ((ChatActivity) fragment).getCurrentUser() != null && ((ChatActivity) fragment).getCurrentUser().id == user.id) {
|
||||
titleTextView.setText(LocaleController.getString("ReturnToCall", R.string.ReturnToCall));
|
||||
} else {
|
||||
titleTextView.setText(ContactsController.formatName(user.first_name, user.last_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float hotspotX;
|
||||
public float hotspotY;
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
hotspotX = ev.getX();
|
||||
hotspotY = ev.getY();
|
||||
}
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
|
@ -10,12 +9,9 @@ import android.graphics.PorterDuffXfermode;
|
|||
import android.graphics.RadialGradient;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import org.telegram.messenger.AccountInstance;
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
|
@ -300,10 +296,15 @@ public class FragmentContextViewWavesDrawable {
|
|||
if (currentCallState == VoIPService.STATE_WAIT_INIT || currentCallState == VoIPService.STATE_WAIT_INIT_ACK || currentCallState == VoIPService.STATE_CREATING || currentCallState == VoIPService.STATE_RECONNECTING) {
|
||||
setState(FragmentContextViewWavesDrawable.MUTE_BUTTON_STATE_CONNECTING, animated);
|
||||
} else {
|
||||
TLRPC.TL_groupCallParticipant participant = VoIPService.getSharedInstance().groupCall.participants.get(AccountInstance.getInstance(VoIPService.getSharedInstance().getAccount()).getUserConfig().getClientUserId());
|
||||
if (participant != null && !participant.can_self_unmute && participant.muted && !ChatObject.canManageCalls(VoIPService.getSharedInstance().getChat())) {
|
||||
VoIPService.getSharedInstance().setMicMute(true, false, false);
|
||||
setState(FragmentContextViewWavesDrawable.MUTE_BUTTON_STATE_MUTED_BY_ADMIN, animated);
|
||||
if (VoIPService.getSharedInstance().groupCall != null) {
|
||||
TLRPC.TL_groupCallParticipant participant = VoIPService.getSharedInstance().groupCall.participants.get(AccountInstance.getInstance(VoIPService.getSharedInstance().getAccount()).getUserConfig().getClientUserId());
|
||||
if (participant != null && !participant.can_self_unmute && participant.muted && !ChatObject.canManageCalls(VoIPService.getSharedInstance().getChat())) {
|
||||
VoIPService.getSharedInstance().setMicMute(true, false, false);
|
||||
setState(FragmentContextViewWavesDrawable.MUTE_BUTTON_STATE_MUTED_BY_ADMIN, animated);
|
||||
} else {
|
||||
boolean isMuted = VoIPService.getSharedInstance().isMicMute();
|
||||
setState(isMuted ? FragmentContextViewWavesDrawable.MUTE_BUTTON_STATE_MUTE : FragmentContextViewWavesDrawable.MUTE_BUTTON_STATE_UNMUTE, animated);
|
||||
}
|
||||
} else {
|
||||
boolean isMuted = VoIPService.getSharedInstance().isMicMute();
|
||||
setState(isMuted ? FragmentContextViewWavesDrawable.MUTE_BUTTON_STATE_MUTE : FragmentContextViewWavesDrawable.MUTE_BUTTON_STATE_UNMUTE, animated);
|
||||
|
|
|
@ -70,31 +70,12 @@ import java.util.HashSet;
|
|||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class GroupVoipInviteAlert extends BottomSheet {
|
||||
public class GroupVoipInviteAlert extends UsersAlertBase {
|
||||
|
||||
private FrameLayout frameLayout;
|
||||
private RecyclerListView listView;
|
||||
private SearchAdapter searchListViewAdapter;
|
||||
private ListAdapter listViewAdapter;
|
||||
private Drawable shadowDrawable;
|
||||
private View shadow;
|
||||
private AnimatorSet shadowAnimation;
|
||||
private StickerEmptyView emptyView;
|
||||
private FlickerLoadingView flickerLoadingView;
|
||||
private SearchField searchView;
|
||||
|
||||
private RectF rect = new RectF();
|
||||
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
private String linkToCopy;
|
||||
|
||||
private int scrollOffsetY;
|
||||
private final SearchAdapter searchAdapter;
|
||||
|
||||
private int delayResults;
|
||||
|
||||
private float colorProgress;
|
||||
private int backgroundColor;
|
||||
|
||||
private TLRPC.Chat currentChat;
|
||||
private TLRPC.ChatFull info;
|
||||
|
||||
|
@ -129,323 +110,37 @@ public class GroupVoipInviteAlert extends BottomSheet {
|
|||
void needOpenSearch(MotionEvent ev, EditTextBoldCursor editText);
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private class SearchField extends FrameLayout {
|
||||
|
||||
private View searchBackground;
|
||||
private ImageView searchIconImageView;
|
||||
private ImageView clearSearchImageView;
|
||||
private CloseProgressDrawable2 progressDrawable;
|
||||
private EditTextBoldCursor searchEditText;
|
||||
private View backgroundView;
|
||||
|
||||
public SearchField(Context context) {
|
||||
super(context);
|
||||
|
||||
searchBackground = new View(context);
|
||||
searchBackground.setBackgroundDrawable(Theme.createRoundRectDrawable(AndroidUtilities.dp(18), Theme.getColor(Theme.key_voipgroup_searchBackground)));
|
||||
addView(searchBackground, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 36, Gravity.LEFT | Gravity.TOP, 14, 11, 14, 0));
|
||||
|
||||
searchIconImageView = new ImageView(context);
|
||||
searchIconImageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
searchIconImageView.setImageResource(R.drawable.smiles_inputsearch);
|
||||
searchIconImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_voipgroup_searchPlaceholder), PorterDuff.Mode.MULTIPLY));
|
||||
addView(searchIconImageView, LayoutHelper.createFrame(36, 36, Gravity.LEFT | Gravity.TOP, 16, 11, 0, 0));
|
||||
|
||||
clearSearchImageView = new ImageView(context);
|
||||
clearSearchImageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
clearSearchImageView.setImageDrawable(progressDrawable = new CloseProgressDrawable2());
|
||||
progressDrawable.setSide(AndroidUtilities.dp(7));
|
||||
clearSearchImageView.setScaleX(0.1f);
|
||||
clearSearchImageView.setScaleY(0.1f);
|
||||
clearSearchImageView.setAlpha(0.0f);
|
||||
clearSearchImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_voipgroup_searchPlaceholder), PorterDuff.Mode.MULTIPLY));
|
||||
addView(clearSearchImageView, LayoutHelper.createFrame(36, 36, Gravity.RIGHT | Gravity.TOP, 14, 11, 14, 0));
|
||||
clearSearchImageView.setOnClickListener(v -> {
|
||||
searchEditText.setText("");
|
||||
AndroidUtilities.showKeyboard(searchEditText);
|
||||
});
|
||||
|
||||
searchEditText = new EditTextBoldCursor(context) {
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
||||
MotionEvent e = MotionEvent.obtain(event);
|
||||
e.setLocation(e.getRawX(), e.getRawY() - containerView.getTranslationY());
|
||||
if (e.getAction() == MotionEvent.ACTION_UP) {
|
||||
e.setAction(MotionEvent.ACTION_CANCEL);
|
||||
}
|
||||
listView.dispatchTouchEvent(e);
|
||||
e.recycle();
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
};
|
||||
searchEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
searchEditText.setHintTextColor(Theme.getColor(Theme.key_voipgroup_searchPlaceholder));
|
||||
searchEditText.setTextColor(Theme.getColor(Theme.key_voipgroup_searchText));
|
||||
searchEditText.setBackgroundDrawable(null);
|
||||
searchEditText.setPadding(0, 0, 0, 0);
|
||||
searchEditText.setMaxLines(1);
|
||||
searchEditText.setLines(1);
|
||||
searchEditText.setSingleLine(true);
|
||||
searchEditText.setImeOptions(EditorInfo.IME_ACTION_SEARCH | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||
searchEditText.setHint(LocaleController.getString("VoipGroupSearchMembers", R.string.VoipGroupSearchMembers));
|
||||
searchEditText.setCursorColor(Theme.getColor(Theme.key_voipgroup_searchText));
|
||||
searchEditText.setCursorSize(AndroidUtilities.dp(20));
|
||||
searchEditText.setCursorWidth(1.5f);
|
||||
addView(searchEditText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 40, Gravity.LEFT | Gravity.TOP, 16 + 38, 9, 16 + 30, 0));
|
||||
searchEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
boolean show = searchEditText.length() > 0;
|
||||
boolean showed = clearSearchImageView.getAlpha() != 0;
|
||||
if (show != showed) {
|
||||
clearSearchImageView.animate()
|
||||
.alpha(show ? 1.0f : 0.0f)
|
||||
.setDuration(150)
|
||||
.scaleX(show ? 1.0f : 0.1f)
|
||||
.scaleY(show ? 1.0f : 0.1f)
|
||||
.start();
|
||||
}
|
||||
String text = searchEditText.getText().toString();
|
||||
int oldItemsCount = listView.getAdapter() == null ? 0 : listView.getAdapter().getItemCount();
|
||||
searchListViewAdapter.searchUsers(text);
|
||||
if (TextUtils.isEmpty(text) && listView != null && listView.getAdapter() != listViewAdapter) {
|
||||
listView.setAnimateEmptyView(false, 0);
|
||||
listView.setAdapter(listViewAdapter);
|
||||
listView.setAnimateEmptyView(true, 0);
|
||||
if (oldItemsCount == 0) {
|
||||
showItemsAnimated(0);
|
||||
}
|
||||
}
|
||||
flickerLoadingView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
searchEditText.setOnEditorActionListener((v, actionId, event) -> {
|
||||
if (event != null && (event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_SEARCH || event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
|
||||
AndroidUtilities.hideKeyboard(searchEditText);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
public void hideKeyboard() {
|
||||
AndroidUtilities.hideKeyboard(searchEditText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
delegate.needOpenSearch(ev, searchEditText);
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
@Override
|
||||
protected void updateColorKeys() {
|
||||
keyScrollUp = Theme.key_voipgroup_scrollUp;
|
||||
keyListSelector = Theme.key_voipgroup_listSelector;
|
||||
keySearchBackground = Theme.key_voipgroup_searchBackground;
|
||||
keyInviteMembersBackground = Theme.key_voipgroup_inviteMembersBackground;
|
||||
keyListViewBackground = Theme.key_voipgroup_listViewBackground;
|
||||
keyActionBarUnscrolled = Theme.key_voipgroup_actionBarUnscrolled;
|
||||
keyNameText = Theme.key_voipgroup_nameText;
|
||||
keyLastSeenText = Theme.key_voipgroup_lastSeenText;
|
||||
keyLastSeenTextUnscrolled = Theme.key_voipgroup_lastSeenTextUnscrolled;
|
||||
keySearchPlaceholder = Theme.key_voipgroup_searchPlaceholder;
|
||||
keySearchText = Theme.key_voipgroup_searchText;
|
||||
keySearchIcon = Theme.key_voipgroup_mutedIcon;
|
||||
keySearchIconUnscrolled = Theme.key_voipgroup_mutedIconUnscrolled;
|
||||
}
|
||||
|
||||
public static final Property<GroupVoipInviteAlert, Float> COLOR_PROGRESS = new AnimationProperties.FloatProperty<GroupVoipInviteAlert>("colorProgress") {
|
||||
@Override
|
||||
public void setValue(GroupVoipInviteAlert object, float value) {
|
||||
object.setColorProgress(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(GroupVoipInviteAlert object) {
|
||||
return object.getColorProgress();
|
||||
}
|
||||
};
|
||||
|
||||
public GroupVoipInviteAlert(final Context context, int account, TLRPC.Chat chat, TLRPC.ChatFull chatFull, SparseArray<TLRPC.TL_groupCallParticipant> participants, HashSet<Integer> invited) {
|
||||
super(context, false);
|
||||
super(context, false, account);
|
||||
|
||||
setDimBehindAlpha(75);
|
||||
|
||||
currentAccount = account;
|
||||
currentChat = chat;
|
||||
info = chatFull;
|
||||
ignoredUsers = participants;
|
||||
invitedUsers = invited;
|
||||
|
||||
shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate();
|
||||
|
||||
containerView = new FrameLayout(context) {
|
||||
|
||||
private boolean ignoreLayout = false;
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int totalHeight = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
ignoreLayout = true;
|
||||
setPadding(backgroundPaddingLeft, AndroidUtilities.statusBarHeight, backgroundPaddingLeft, 0);
|
||||
ignoreLayout = false;
|
||||
}
|
||||
int availableHeight = totalHeight - getPaddingTop();
|
||||
int padding;
|
||||
if (keyboardVisible) {
|
||||
padding = AndroidUtilities.dp(8);
|
||||
setAllowNestedScroll(false);
|
||||
} else {
|
||||
padding = availableHeight - (availableHeight / 5 * 3) + AndroidUtilities.dp(8);
|
||||
setAllowNestedScroll(true);
|
||||
}
|
||||
if (listView.getPaddingTop() != padding) {
|
||||
ignoreLayout = true;
|
||||
listView.setPadding(0, padding, 0, 0);
|
||||
ignoreLayout = false;
|
||||
}
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(totalHeight, MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getY() < scrollOffsetY) {
|
||||
dismiss();
|
||||
return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e) {
|
||||
return !isDismissed() && super.onTouchEvent(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
if (ignoreLayout) {
|
||||
return;
|
||||
}
|
||||
super.requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
canvas.save();
|
||||
int y = scrollOffsetY - backgroundPaddingTop + AndroidUtilities.dp(6);
|
||||
int top = scrollOffsetY - backgroundPaddingTop - AndroidUtilities.dp(13);
|
||||
int height = getMeasuredHeight() + AndroidUtilities.dp(30) + backgroundPaddingTop;
|
||||
int statusBarHeight = 0;
|
||||
float radProgress = 1.0f;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
top += AndroidUtilities.statusBarHeight;
|
||||
y += AndroidUtilities.statusBarHeight;
|
||||
height -= AndroidUtilities.statusBarHeight;
|
||||
|
||||
if (top + backgroundPaddingTop < AndroidUtilities.statusBarHeight * 2) {
|
||||
int diff = Math.min(AndroidUtilities.statusBarHeight, AndroidUtilities.statusBarHeight * 2 - top - backgroundPaddingTop);
|
||||
top -= diff;
|
||||
height += diff;
|
||||
radProgress = 1.0f - Math.min(1.0f, (diff * 2) / (float) AndroidUtilities.statusBarHeight);
|
||||
}
|
||||
if (top + backgroundPaddingTop < AndroidUtilities.statusBarHeight) {
|
||||
statusBarHeight = Math.min(AndroidUtilities.statusBarHeight, AndroidUtilities.statusBarHeight - top - backgroundPaddingTop);
|
||||
}
|
||||
}
|
||||
|
||||
shadowDrawable.setBounds(0, top, getMeasuredWidth(), height);
|
||||
shadowDrawable.draw(canvas);
|
||||
|
||||
if (radProgress != 1.0f) {
|
||||
Theme.dialogs_onlineCirclePaint.setColor(backgroundColor);
|
||||
rect.set(backgroundPaddingLeft, backgroundPaddingTop + top, getMeasuredWidth() - backgroundPaddingLeft, backgroundPaddingTop + top + AndroidUtilities.dp(24));
|
||||
canvas.drawRoundRect(rect, AndroidUtilities.dp(12) * radProgress, AndroidUtilities.dp(12) * radProgress, Theme.dialogs_onlineCirclePaint);
|
||||
}
|
||||
|
||||
int w = AndroidUtilities.dp(36);
|
||||
rect.set((getMeasuredWidth() - w) / 2, y, (getMeasuredWidth() + w) / 2, y + AndroidUtilities.dp(4));
|
||||
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(Theme.key_voipgroup_scrollUp));
|
||||
canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), Theme.dialogs_onlineCirclePaint);
|
||||
|
||||
if (statusBarHeight > 0) {
|
||||
int finalColor = Color.argb(0xff, (int) (Color.red(backgroundColor) * 0.8f), (int) (Color.green(backgroundColor) * 0.8f), (int) (Color.blue(backgroundColor) * 0.8f));
|
||||
Theme.dialogs_onlineCirclePaint.setColor(finalColor);
|
||||
canvas.drawRect(backgroundPaddingLeft, AndroidUtilities.statusBarHeight - statusBarHeight, getMeasuredWidth() - backgroundPaddingLeft, AndroidUtilities.statusBarHeight, Theme.dialogs_onlineCirclePaint);
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.save();
|
||||
canvas.clipRect(0, getPaddingTop(), getMeasuredWidth(), getMeasuredHeight());
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
};
|
||||
containerView.setWillNotDraw(false);
|
||||
containerView.setClipChildren(false);
|
||||
containerView.setPadding(backgroundPaddingLeft, 0, backgroundPaddingLeft, 0);
|
||||
|
||||
frameLayout = new FrameLayout(context);
|
||||
|
||||
searchView = new SearchField(context);
|
||||
frameLayout.addView(searchView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
|
||||
|
||||
flickerLoadingView = new FlickerLoadingView(context);
|
||||
flickerLoadingView.setViewType(FlickerLoadingView.USERS_TYPE);
|
||||
flickerLoadingView.showDate(false);
|
||||
flickerLoadingView.setUseHeaderOffset(true);
|
||||
flickerLoadingView.setColors(Theme.key_voipgroup_inviteMembersBackground, Theme.key_voipgroup_searchBackground, Theme.key_voipgroup_actionBarUnscrolled);
|
||||
|
||||
emptyView = new StickerEmptyView(context, flickerLoadingView, StickerEmptyView.STICKER_TYPE_SEARCH);
|
||||
emptyView.addView(flickerLoadingView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0,0,2,0,0));
|
||||
emptyView.title.setText(LocaleController.getString("NoResult", R.string.NoResult));
|
||||
emptyView.subtitle.setText(LocaleController.getString("SearchEmptyViewFilteredSubtitle2", R.string.SearchEmptyViewFilteredSubtitle2));
|
||||
emptyView.setVisibility(View.GONE);
|
||||
emptyView.setAnimateLayoutChange(true);
|
||||
emptyView.showProgress(true, false);
|
||||
emptyView.setColors(Theme.key_voipgroup_nameText, Theme.key_voipgroup_lastSeenText, Theme.key_voipgroup_inviteMembersBackground, Theme.key_voipgroup_searchBackground);
|
||||
containerView.addView(emptyView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 58 + 4, 0, 0));
|
||||
|
||||
searchListViewAdapter = new SearchAdapter(context);
|
||||
|
||||
listView = new RecyclerListView(context) {
|
||||
@Override
|
||||
protected boolean allowSelectChildAtPosition(float x, float y) {
|
||||
return y >= scrollOffsetY + AndroidUtilities.dp(48) + (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslationY(float translationY) {
|
||||
super.setTranslationY(translationY);
|
||||
int[] ii = new int[2];
|
||||
getLocationInWindow(ii);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean emptyViewIsVisible() {
|
||||
if (getAdapter() == null) {
|
||||
return false;
|
||||
}
|
||||
return getAdapter().getItemCount() <= 2;
|
||||
}
|
||||
};
|
||||
listView.setTag(13);
|
||||
listView.setPadding(0, 0, 0, AndroidUtilities.dp(48));
|
||||
listView.setClipToPadding(false);
|
||||
listView.setHideIfEmpty(false);
|
||||
listView.setSelectorDrawableColor(Theme.getColor(Theme.key_voipgroup_listSelector));
|
||||
FillLastLinearLayoutManager layoutManager = new FillLastLinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false, AndroidUtilities.dp(8), listView);
|
||||
layoutManager.setBind(false);
|
||||
listView.setLayoutManager(layoutManager);
|
||||
listView.setHorizontalScrollBarEnabled(false);
|
||||
listView.setVerticalScrollBarEnabled(false);
|
||||
containerView.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 0));
|
||||
listView.setAdapter(listViewAdapter = new ListAdapter(context));
|
||||
currentChat = chat;
|
||||
info = chatFull;
|
||||
ignoredUsers = participants;
|
||||
invitedUsers = invited;
|
||||
listView.setOnItemClickListener((view, position) -> {
|
||||
if (position == addNewRow) {
|
||||
delegate.copyInviteLink();
|
||||
|
@ -458,89 +153,18 @@ public class GroupVoipInviteAlert extends BottomSheet {
|
|||
delegate.inviteUser(cell.getUserId());
|
||||
}
|
||||
});
|
||||
listView.setOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
if (scrollOffsetY + backgroundPaddingTop + AndroidUtilities.dp(13) < AndroidUtilities.statusBarHeight * 2 && listView.canScrollVertically(1)) {
|
||||
View child = listView.getChildAt(0);
|
||||
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findViewHolderForAdapterPosition(0);
|
||||
if (holder != null && holder.itemView.getTop() > 0) {
|
||||
listView.smoothScrollBy(0, holder.itemView.getTop());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
FrameLayout.LayoutParams frameLayoutParams = new FrameLayout.LayoutParams(LayoutHelper.MATCH_PARENT, AndroidUtilities.getShadowHeight(), Gravity.TOP | Gravity.LEFT);
|
||||
frameLayoutParams.topMargin = AndroidUtilities.dp(58);
|
||||
shadow = new View(context);
|
||||
shadow.setBackgroundColor(Theme.getColor(Theme.key_dialogShadowLine));
|
||||
shadow.setAlpha(0.0f);
|
||||
shadow.setTag(1);
|
||||
containerView.addView(shadow, frameLayoutParams);
|
||||
|
||||
containerView.addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 58, Gravity.LEFT | Gravity.TOP));
|
||||
|
||||
setColorProgress(0.0f);
|
||||
|
||||
searchListViewAdapter = searchAdapter = new SearchAdapter(context);
|
||||
listView.setAdapter(listViewAdapter = new ListAdapter(context));
|
||||
loadChatParticipants(0, 200);
|
||||
updateRows();
|
||||
|
||||
listView.setEmptyView(emptyView);
|
||||
listView.setAnimateEmptyView(true, 0);
|
||||
}
|
||||
|
||||
private float getColorProgress() {
|
||||
return colorProgress;
|
||||
}
|
||||
|
||||
private void setColorProgress(float progress) {
|
||||
colorProgress = progress;
|
||||
backgroundColor = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_inviteMembersBackground), Theme.getColor(Theme.key_voipgroup_listViewBackground), progress, 1.0f);
|
||||
shadowDrawable.setColorFilter(new PorterDuffColorFilter(backgroundColor, PorterDuff.Mode.MULTIPLY));
|
||||
frameLayout.setBackgroundColor(backgroundColor);
|
||||
navBarColor = backgroundColor;
|
||||
listView.setGlowColor(backgroundColor);
|
||||
|
||||
int color = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_lastSeenTextUnscrolled), Theme.getColor(Theme.key_voipgroup_lastSeenText), progress, 1.0f);
|
||||
int color2 = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_mutedIconUnscrolled), Theme.getColor(Theme.key_voipgroup_mutedIcon), progress, 1.0f);//
|
||||
for (int a = 0, N = listView.getChildCount(); a < N; a++) {
|
||||
View child = listView.getChildAt(a);
|
||||
if (child instanceof GroupCallTextCell) {
|
||||
GroupCallTextCell cell = (GroupCallTextCell) child;
|
||||
cell.setColors(color, color);
|
||||
} else if (child instanceof GroupCallUserCell) {
|
||||
GroupCallUserCell cell = (GroupCallUserCell) child;
|
||||
cell.setGrayIconColor(shadow.getTag() != null ? Theme.key_voipgroup_mutedIcon : Theme.key_voipgroup_mutedIconUnscrolled, color2);
|
||||
}
|
||||
}
|
||||
containerView.invalidate();
|
||||
listView.invalidate();
|
||||
container.invalidate();
|
||||
setColorProgress(0.0f);
|
||||
}
|
||||
|
||||
public void setDelegate(GroupVoipInviteAlertDelegate groupVoipInviteAlertDelegate) {
|
||||
delegate = groupVoipInviteAlertDelegate;
|
||||
}
|
||||
|
||||
private int getCurrentTop() {
|
||||
if (listView.getChildCount() != 0) {
|
||||
View child = listView.getChildAt(0);
|
||||
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findContainingViewHolder(child);
|
||||
if (holder != null) {
|
||||
return listView.getPaddingTop() - (holder.getAdapterPosition() == 0 && child.getTop() >= 0 ? child.getTop() : 0);
|
||||
}
|
||||
}
|
||||
return -1000;
|
||||
}
|
||||
|
||||
private void updateRows() {
|
||||
addNewRow = -1;
|
||||
emptyRow = -1;
|
||||
|
@ -581,107 +205,6 @@ public class GroupVoipInviteAlert extends BottomSheet {
|
|||
lastRow = rowCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDismissWithSwipe() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismiss() {
|
||||
AndroidUtilities.hideKeyboard(searchView.searchEditText);
|
||||
super.dismiss();
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void updateLayout() {
|
||||
if (listView.getChildCount() <= 0) {
|
||||
return;
|
||||
}
|
||||
View child = listView.getChildAt(0);
|
||||
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findContainingViewHolder(child);
|
||||
int top = child.getTop() - AndroidUtilities.dp(8);
|
||||
int newOffset = top > 0 && holder != null && holder.getAdapterPosition() == 0 ? top : 0;
|
||||
if (top >= 0 && holder != null && holder.getAdapterPosition() == 0) {
|
||||
newOffset = top;
|
||||
runShadowAnimation(false);
|
||||
} else {
|
||||
runShadowAnimation(true);
|
||||
}
|
||||
if (scrollOffsetY != newOffset) {
|
||||
listView.setTopGlowOffset(scrollOffsetY = (int) (newOffset));
|
||||
frameLayout.setTranslationY(scrollOffsetY);
|
||||
emptyView.setTranslationY(scrollOffsetY);
|
||||
containerView.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void runShadowAnimation(final boolean show) {
|
||||
if (show && shadow.getTag() != null || !show && shadow.getTag() == null) {
|
||||
shadow.setTag(show ? null : 1);
|
||||
if (show) {
|
||||
shadow.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (shadowAnimation != null) {
|
||||
shadowAnimation.cancel();
|
||||
}
|
||||
shadowAnimation = new AnimatorSet();
|
||||
shadowAnimation.playTogether(ObjectAnimator.ofFloat(shadow, View.ALPHA, show ? 1.0f : 0.0f));
|
||||
shadowAnimation.setDuration(150);
|
||||
shadowAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (shadowAnimation != null && shadowAnimation.equals(animation)) {
|
||||
if (!show) {
|
||||
shadow.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
shadowAnimation = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
if (shadowAnimation != null && shadowAnimation.equals(animation)) {
|
||||
shadowAnimation = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
shadowAnimation.start();
|
||||
}
|
||||
}
|
||||
|
||||
private void showItemsAnimated(int from) {
|
||||
if (!isShowing()) {
|
||||
return;
|
||||
}
|
||||
listView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
listView.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
int n = listView.getChildCount();
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
for (int i = 0; i < n; i++) {
|
||||
View child = listView.getChildAt(i);
|
||||
int position = listView.getChildAdapterPosition(child);
|
||||
if (position < from) {
|
||||
continue;
|
||||
}
|
||||
if (position == 1 && listView.getAdapter() == searchListViewAdapter && child instanceof GraySectionCell) {
|
||||
child = ((GraySectionCell) child).getTextView();
|
||||
}
|
||||
child.setAlpha(0);
|
||||
int s = Math.min(listView.getMeasuredHeight(), Math.max(0, child.getTop()));
|
||||
int delay = (int) ((s / (float) listView.getMeasuredHeight()) * 100);
|
||||
ObjectAnimator a = ObjectAnimator.ofFloat(child, View.ALPHA, 0, 1f);
|
||||
a.setStartDelay(delay);
|
||||
a.setDuration(200);
|
||||
animatorSet.playTogether(a);
|
||||
}
|
||||
animatorSet.start();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadChatParticipants(int offset, int count) {
|
||||
if (loadingUsers) {
|
||||
return;
|
||||
|
@ -690,7 +213,8 @@ public class GroupVoipInviteAlert extends BottomSheet {
|
|||
loadChatParticipants(offset, count, true);
|
||||
}
|
||||
|
||||
private void loadChatParticipants(int offset, int count, boolean reset) {
|
||||
|
||||
protected void loadChatParticipants(int offset, int count, boolean reset) {
|
||||
if (!ChatObject.isChannel(currentChat)) {
|
||||
loadingUsers = false;
|
||||
participants.clear();
|
||||
|
@ -1364,4 +888,13 @@ public class GroupVoipInviteAlert extends BottomSheet {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void search(String text) {
|
||||
searchAdapter.searchUsers(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSearchViewTouched(MotionEvent ev, EditTextBoldCursor searchEditText) {
|
||||
delegate.needOpenSearch(ev, searchEditText);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ public class GroupedPhotosListView extends View implements GestureDetector.OnGes
|
|||
}
|
||||
}
|
||||
if (!changed) {
|
||||
if (newCount != currentPhotos.size() || currentObjects.indexOf(currentObject) == -1) {
|
||||
if (newCount != currentPhotos.size() || !currentObjects.contains(currentObject)) {
|
||||
changed = true;
|
||||
} else {
|
||||
int newImageIndex = currentObjects.indexOf(currentObject);
|
||||
|
|
|
@ -11,6 +11,7 @@ package org.telegram.ui.Components;
|
|||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -136,12 +137,12 @@ public class ImageUpdater implements NotificationCenter.NotificationCenterDelega
|
|||
delegate = imageUpdaterDelegate;
|
||||
}
|
||||
|
||||
public void openMenu(boolean hasAvatar, Runnable onDeleteAvatar) {
|
||||
public void openMenu(boolean hasAvatar, Runnable onDeleteAvatar, DialogInterface.OnDismissListener onDismiss) {
|
||||
if (parentFragment == null || parentFragment.getParentActivity() == null) {
|
||||
return;
|
||||
}
|
||||
if (useAttachMenu) {
|
||||
openAttachMenu();
|
||||
openAttachMenu(onDismiss);
|
||||
return;
|
||||
}
|
||||
BottomSheet.Builder builder = new BottomSheet.Builder(parentFragment.getParentActivity());
|
||||
|
@ -196,6 +197,7 @@ public class ImageUpdater implements NotificationCenter.NotificationCenterDelega
|
|||
}
|
||||
});
|
||||
BottomSheet sheet = builder.create();
|
||||
sheet.setOnHideListener(onDismiss);
|
||||
parentFragment.showDialog(sheet);
|
||||
if (hasAvatar) {
|
||||
sheet.setItemColor(items.size() - 1, Theme.getColor(Theme.key_dialogTextRed2), Theme.getColor(Theme.key_dialogRedIcon));
|
||||
|
@ -296,7 +298,7 @@ public class ImageUpdater implements NotificationCenter.NotificationCenterDelega
|
|||
parentFragment.presentFragment(fragment);
|
||||
}
|
||||
|
||||
private void openAttachMenu() {
|
||||
private void openAttachMenu(DialogInterface.OnDismissListener onDismissListener) {
|
||||
if (parentFragment == null || parentFragment.getParentActivity() == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -308,6 +310,7 @@ public class ImageUpdater implements NotificationCenter.NotificationCenterDelega
|
|||
AndroidUtilities.hideKeyboard(parentFragment.getFragmentView().findFocus());
|
||||
}
|
||||
chatAttachAlert.init();
|
||||
chatAttachAlert.setOnHideListener(onDismissListener);
|
||||
parentFragment.showDialog(chatAttachAlert);
|
||||
}
|
||||
|
||||
|
@ -874,7 +877,7 @@ public class ImageUpdater implements NotificationCenter.NotificationCenterDelega
|
|||
return;
|
||||
}
|
||||
uploadingVideo = (String) args[1];
|
||||
parentFragment.getFileLoader().uploadFile(uploadingVideo, false, false, (int) convertingVideo.videoEditedInfo.estimatedSize, ConnectionsManager.FileTypeVideo);
|
||||
parentFragment.getFileLoader().uploadFile(uploadingVideo, false, false, (int) convertingVideo.videoEditedInfo.estimatedSize, ConnectionsManager.FileTypeVideo, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* This is the source code of Telegram for Android v. 5.x.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2018.
|
||||
*/
|
||||
|
||||
package org.telegram.ui.Components;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.SendMessagesHelper;
|
||||
import org.telegram.ui.ActionBar.BottomSheet;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.ChatActivity;
|
||||
|
||||
public class ImportingAlert extends BottomSheet implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
private TextView[] importCountTextView = new TextView[2];
|
||||
private TextView percentTextView;
|
||||
private LineProgressView lineProgressView;
|
||||
private ChatActivity parentFragment;
|
||||
private RLottieImageView imageView;
|
||||
private BottomSheetCell cell;
|
||||
private boolean compteled;
|
||||
private RLottieDrawable completedDrawable;
|
||||
private TextView[] infoTextView = new TextView[2];
|
||||
|
||||
public static class BottomSheetCell extends FrameLayout {
|
||||
|
||||
private View background;
|
||||
private TextView textView;
|
||||
private RLottieImageView imageView;
|
||||
private LinearLayout linearLayout;
|
||||
|
||||
public BottomSheetCell(Context context) {
|
||||
super(context);
|
||||
|
||||
background = new View(context);
|
||||
background.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed)));
|
||||
addView(background, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 16, 16, 16, 16));
|
||||
|
||||
linearLayout = new LinearLayout(context);
|
||||
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
|
||||
|
||||
imageView = new RLottieImageView(context);
|
||||
imageView.setBackground(Theme.createCircleDrawable(AndroidUtilities.dp(20), Theme.getColor(Theme.key_featuredStickers_buttonText)));
|
||||
imageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_featuredStickers_addButton), PorterDuff.Mode.MULTIPLY));
|
||||
imageView.setAnimation(R.raw.import_check, 26, 26);
|
||||
imageView.setScaleX(0.8f);
|
||||
imageView.setScaleY(0.8f);
|
||||
linearLayout.addView(imageView, LayoutHelper.createLinear(20, 20, Gravity.CENTER_VERTICAL));
|
||||
|
||||
textView = new TextView(context);
|
||||
textView.setLines(1);
|
||||
textView.setSingleLine(true);
|
||||
textView.setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
textView.setGravity(Gravity.CENTER);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
linearLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 10, 0, 0, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(80), MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
public void setTextColor(int color) {
|
||||
textView.setTextColor(color);
|
||||
}
|
||||
|
||||
public void setGravity(int gravity) {
|
||||
textView.setGravity(gravity);
|
||||
}
|
||||
|
||||
public void setText(CharSequence text) {
|
||||
textView.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private final Runnable onFinishCallback = () -> {
|
||||
if (compteled) {
|
||||
imageView.getAnimatedDrawable().setAutoRepeat(0);
|
||||
imageView.setAnimation(completedDrawable);
|
||||
imageView.playAnimation();
|
||||
}
|
||||
};
|
||||
|
||||
public ImportingAlert(final Context context, ChatActivity chatActivity) {
|
||||
super(context, false);
|
||||
setApplyBottomPadding(false);
|
||||
setApplyTopPadding(false);
|
||||
parentFragment = chatActivity;
|
||||
|
||||
FrameLayout frameLayout = new FrameLayout(context);
|
||||
setCustomView(frameLayout);
|
||||
|
||||
TextView textView = new TextView(context);
|
||||
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
|
||||
textView.setText(LocaleController.getString("ImportImportingTitle", R.string.ImportImportingTitle));
|
||||
textView.setSingleLine(true);
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 17, 20, 17, 0));
|
||||
|
||||
completedDrawable = new RLottieDrawable(R.raw.import_finish, "" + R.raw.import_finish, AndroidUtilities.dp(120), AndroidUtilities.dp(120), false, null);
|
||||
completedDrawable.setAllowDecodeSingleFrame(true);
|
||||
|
||||
imageView = new RLottieImageView(context);
|
||||
imageView.setAutoRepeat(true);
|
||||
imageView.setAnimation(R.raw.import_loop, 120, 120);
|
||||
imageView.playAnimation();
|
||||
frameLayout.addView(imageView, LayoutHelper.createFrame(160, 160, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 17, 79, 17, 0));
|
||||
imageView.getAnimatedDrawable().setOnFinishCallback(onFinishCallback, 178);
|
||||
|
||||
SendMessagesHelper.ImportingHistory importingHistory = parentFragment.getSendMessagesHelper().getImportingHistory(parentFragment.getDialogId());
|
||||
|
||||
percentTextView = new TextView(context);
|
||||
percentTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
percentTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24);
|
||||
percentTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
|
||||
percentTextView.setText(String.format("%d%%", importingHistory.uploadProgress));
|
||||
frameLayout.addView(percentTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 17, 262, 17, 0));
|
||||
|
||||
lineProgressView = new LineProgressView(getContext());
|
||||
lineProgressView.setProgress(importingHistory.uploadProgress / 100.0f, false);
|
||||
lineProgressView.setProgressColor(Theme.getColor(Theme.key_featuredStickers_addButton));
|
||||
lineProgressView.setBackColor(Theme.getColor(Theme.key_dialogLineProgressBackground));
|
||||
frameLayout.addView(lineProgressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 4, Gravity.LEFT | Gravity.TOP, 50, 307, 50, 0));
|
||||
|
||||
cell = new BottomSheetCell(context);
|
||||
cell.setBackground(null);
|
||||
cell.setText(LocaleController.getString("ImportDone", R.string.ImportDone));
|
||||
cell.setVisibility(View.INVISIBLE);
|
||||
cell.background.setOnClickListener(v -> dismiss());
|
||||
cell.background.setPivotY(AndroidUtilities.dp(48));
|
||||
cell.background.setScaleY(0.04f);
|
||||
frameLayout.addView(cell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.LEFT | Gravity.TOP, 34, 247, 34, 0));
|
||||
|
||||
for (int a = 0; a < 2; a++) {
|
||||
importCountTextView[a] = new TextView(context);
|
||||
importCountTextView[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
importCountTextView[a].setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
importCountTextView[a].setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
|
||||
frameLayout.addView(importCountTextView[a], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 17, 340, 17, 0));
|
||||
|
||||
infoTextView[a] = new TextView(context);
|
||||
infoTextView[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
infoTextView[a].setTextColor(Theme.getColor(Theme.key_dialogTextGray3));
|
||||
infoTextView[a].setGravity(Gravity.CENTER_HORIZONTAL);
|
||||
frameLayout.addView(infoTextView[a], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 30, 368, 30, 44));
|
||||
|
||||
if (a == 0) {
|
||||
infoTextView[a].setText(LocaleController.getString("ImportImportingInfo", R.string.ImportImportingInfo));
|
||||
importCountTextView[a].setText(LocaleController.formatString("ImportCount", R.string.ImportCount, AndroidUtilities.formatFileSize(importingHistory.getUploadedCount()), AndroidUtilities.formatFileSize(importingHistory.getTotalCount())));
|
||||
} else {
|
||||
infoTextView[a].setText(LocaleController.getString("ImportDoneInfo", R.string.ImportDoneInfo));
|
||||
importCountTextView[a].setText(LocaleController.getString("ImportDoneTitle", R.string.ImportDoneTitle));
|
||||
|
||||
infoTextView[a].setAlpha(0.0f);
|
||||
infoTextView[a].setTranslationY(AndroidUtilities.dp(10));
|
||||
importCountTextView[a].setAlpha(0.0f);
|
||||
importCountTextView[a].setTranslationY(AndroidUtilities.dp(10));
|
||||
}
|
||||
}
|
||||
|
||||
parentFragment.getNotificationCenter().addObserver(this, NotificationCenter.historyImportProgressChanged);
|
||||
}
|
||||
|
||||
public void setCompteled() {
|
||||
compteled = true;
|
||||
imageView.setAutoRepeat(false);
|
||||
cell.setVisibility(View.VISIBLE);
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.setDuration(250);
|
||||
animatorSet.setInterpolator(CubicBezierInterpolator.EASE_OUT);
|
||||
animatorSet.playTogether(
|
||||
ObjectAnimator.ofFloat(percentTextView, View.ALPHA, 0.0f),
|
||||
ObjectAnimator.ofFloat(percentTextView, View.TRANSLATION_Y, -AndroidUtilities.dp(10)),
|
||||
ObjectAnimator.ofFloat(infoTextView[0], View.ALPHA, 0.0f),
|
||||
ObjectAnimator.ofFloat(infoTextView[0], View.TRANSLATION_Y, -AndroidUtilities.dp(10)),
|
||||
ObjectAnimator.ofFloat(importCountTextView[0], View.ALPHA, 0.0f),
|
||||
ObjectAnimator.ofFloat(importCountTextView[0], View.TRANSLATION_Y, -AndroidUtilities.dp(10)),
|
||||
ObjectAnimator.ofFloat(infoTextView[1], View.ALPHA, 1.0f),
|
||||
ObjectAnimator.ofFloat(infoTextView[1], View.TRANSLATION_Y, 0),
|
||||
ObjectAnimator.ofFloat(importCountTextView[1], View.ALPHA, 1.0f),
|
||||
ObjectAnimator.ofFloat(importCountTextView[1], View.TRANSLATION_Y, 0),
|
||||
ObjectAnimator.ofFloat(lineProgressView, View.ALPHA, 0),
|
||||
ObjectAnimator.ofFloat(cell.linearLayout, View.TRANSLATION_Y, AndroidUtilities.dp(8), 0)
|
||||
);
|
||||
cell.background.animate().scaleY(1.0f).setInterpolator(new OvershootInterpolator(1.02f)).setDuration(250).start();
|
||||
cell.imageView.animate().scaleY(1.0f).scaleX(1.0f).setInterpolator(new OvershootInterpolator(1.02f)).setDuration(250).start();
|
||||
cell.imageView.playAnimation();
|
||||
animatorSet.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didReceivedNotification(int id, int account, Object... args) {
|
||||
if (id == NotificationCenter.historyImportProgressChanged) {
|
||||
if (args.length > 1) {
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
long dialogId = parentFragment.getDialogId();
|
||||
SendMessagesHelper.ImportingHistory importingHistory = parentFragment.getSendMessagesHelper().getImportingHistory(dialogId);
|
||||
if (importingHistory == null) {
|
||||
setCompteled();
|
||||
return;
|
||||
}
|
||||
if (!compteled) {
|
||||
double timeToEndAnimation = (180 - imageView.getAnimatedDrawable().getCurrentFrame()) * 16.6 + 3000;
|
||||
if (timeToEndAnimation >= importingHistory.timeUntilFinish) {
|
||||
imageView.setAutoRepeat(false);
|
||||
compteled = true;
|
||||
}
|
||||
}
|
||||
|
||||
percentTextView.setText(String.format("%d%%", importingHistory.uploadProgress));
|
||||
importCountTextView[0].setText(LocaleController.formatString("ImportCount", R.string.ImportCount, AndroidUtilities.formatFileSize(importingHistory.getUploadedCount()), AndroidUtilities.formatFileSize(importingHistory.getTotalCount())));
|
||||
lineProgressView.setProgress(importingHistory.uploadProgress / 100.0f, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissInternal() {
|
||||
super.dismissInternal();
|
||||
parentFragment.getNotificationCenter().removeObserver(this, NotificationCenter.historyImportProgressChanged);
|
||||
}
|
||||
}
|
|
@ -2254,7 +2254,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
|
||||
private void didWriteData(File file, long availableSize, boolean last) {
|
||||
if (videoConvertFirstWrite) {
|
||||
FileLoader.getInstance(currentAccount).uploadFile(file.toString(), isSecretChat, false, 1, ConnectionsManager.FileTypeVideo);
|
||||
FileLoader.getInstance(currentAccount).uploadFile(file.toString(), isSecretChat, false, 1, ConnectionsManager.FileTypeVideo, false);
|
||||
videoConvertFirstWrite = false;
|
||||
if (last) {
|
||||
FileLoader.getInstance(currentAccount).checkUploadNewDataAvailable(file.toString(), isSecretChat, availableSize, last ? file.length() : 0);
|
||||
|
|
|
@ -0,0 +1,710 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.tgnet.ConnectionsManager;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.AlertDialog;
|
||||
import org.telegram.ui.ActionBar.BaseFragment;
|
||||
import org.telegram.ui.ActionBar.BottomSheet;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Cells.HeaderCell;
|
||||
import org.telegram.ui.Cells.ShadowSectionCell;
|
||||
import org.telegram.ui.Cells.TextInfoPrivacyCell;
|
||||
import org.telegram.ui.Cells.UserCell;
|
||||
import org.telegram.ui.ManageLinksActivity;
|
||||
import org.telegram.ui.ProfileActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class InviteLinkBottomSheet extends BottomSheet {
|
||||
|
||||
TLRPC.TL_chatInviteExported invite;
|
||||
HashMap<Integer, TLRPC.User> users;
|
||||
TLRPC.ChatFull info;
|
||||
|
||||
int creatorHeaderRow;
|
||||
int creatorRow;
|
||||
int dividerRow;
|
||||
int divider2Row;
|
||||
int usersHeaderRow;
|
||||
int usersStartRow;
|
||||
int usersEndRow;
|
||||
int linkActionRow;
|
||||
int linkInfoRow;
|
||||
int loadingRow;
|
||||
int emptyView;
|
||||
int emptyView2;
|
||||
|
||||
boolean usersLoading;
|
||||
boolean hasMore;
|
||||
|
||||
int rowCount;
|
||||
Adapter adapter;
|
||||
BaseFragment fragment;
|
||||
|
||||
private RecyclerListView listView;
|
||||
private TextView titleTextView;
|
||||
private AnimatorSet shadowAnimation;
|
||||
private View shadow;
|
||||
|
||||
private int scrollOffsetY;
|
||||
private boolean ignoreLayout;
|
||||
private boolean permanent;
|
||||
|
||||
ArrayList<TLRPC.TL_chatInviteImporter> invitedUsers = new ArrayList<>();
|
||||
|
||||
private int chatId;
|
||||
|
||||
public InviteLinkBottomSheet(Context context, TLRPC.TL_chatInviteExported invite, TLRPC.ChatFull info, HashMap<Integer, TLRPC.User> users, BaseFragment fragment, int chatId, boolean permanent) {
|
||||
super(context, false);
|
||||
this.invite = invite;
|
||||
this.users = users;
|
||||
this.fragment = fragment;
|
||||
this.info = info;
|
||||
this.chatId = chatId;
|
||||
this.permanent = permanent;
|
||||
|
||||
containerView = new FrameLayout(context) {
|
||||
|
||||
private RectF rect = new RectF();
|
||||
private boolean fullHeight;
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN && scrollOffsetY != 0 && ev.getY() < scrollOffsetY) {
|
||||
dismiss();
|
||||
return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e) {
|
||||
return !isDismissed() && super.onTouchEvent(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
ignoreLayout = true;
|
||||
setPadding(backgroundPaddingLeft, AndroidUtilities.statusBarHeight, backgroundPaddingLeft, 0);
|
||||
ignoreLayout = false;
|
||||
}
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
|
||||
fullHeight = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
if (ignoreLayout) {
|
||||
return;
|
||||
}
|
||||
super.requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
int top = scrollOffsetY - backgroundPaddingTop - AndroidUtilities.dp(8);
|
||||
int height = getMeasuredHeight() + AndroidUtilities.dp(36) + backgroundPaddingTop;
|
||||
int statusBarHeight = 0;
|
||||
float radProgress = 1.0f;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
top += AndroidUtilities.statusBarHeight;
|
||||
height -= AndroidUtilities.statusBarHeight;
|
||||
|
||||
if (fullHeight) {
|
||||
if (top + backgroundPaddingTop < AndroidUtilities.statusBarHeight * 2) {
|
||||
int diff = Math.min(AndroidUtilities.statusBarHeight, AndroidUtilities.statusBarHeight * 2 - top - backgroundPaddingTop);
|
||||
top -= diff;
|
||||
height += diff;
|
||||
radProgress = 1.0f - Math.min(1.0f, (diff * 2) / (float) AndroidUtilities.statusBarHeight);
|
||||
}
|
||||
if (top + backgroundPaddingTop < AndroidUtilities.statusBarHeight) {
|
||||
statusBarHeight = Math.min(AndroidUtilities.statusBarHeight, AndroidUtilities.statusBarHeight - top - backgroundPaddingTop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shadowDrawable.setBounds(0, top, getMeasuredWidth(), height);
|
||||
shadowDrawable.draw(canvas);
|
||||
|
||||
if (radProgress != 1.0f) {
|
||||
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(Theme.key_dialogBackground));
|
||||
rect.set(backgroundPaddingLeft, backgroundPaddingTop + top, getMeasuredWidth() - backgroundPaddingLeft, backgroundPaddingTop + top + AndroidUtilities.dp(24));
|
||||
canvas.drawRoundRect(rect, AndroidUtilities.dp(12) * radProgress, AndroidUtilities.dp(12) * radProgress, Theme.dialogs_onlineCirclePaint);
|
||||
}
|
||||
|
||||
if (statusBarHeight > 0) {
|
||||
int color1 = Theme.getColor(Theme.key_dialogBackground);
|
||||
int finalColor = Color.argb(0xff, (int) (Color.red(color1) * 0.8f), (int) (Color.green(color1) * 0.8f), (int) (Color.blue(color1) * 0.8f));
|
||||
Theme.dialogs_onlineCirclePaint.setColor(finalColor);
|
||||
canvas.drawRect(backgroundPaddingLeft, AndroidUtilities.statusBarHeight - statusBarHeight, getMeasuredWidth() - backgroundPaddingLeft, AndroidUtilities.statusBarHeight, Theme.dialogs_onlineCirclePaint);
|
||||
}
|
||||
}
|
||||
};
|
||||
containerView.setWillNotDraw(false);
|
||||
|
||||
FrameLayout.LayoutParams frameLayoutParams = new FrameLayout.LayoutParams(LayoutHelper.MATCH_PARENT, AndroidUtilities.getShadowHeight(), Gravity.TOP | Gravity.LEFT);
|
||||
frameLayoutParams.topMargin = AndroidUtilities.dp(48);
|
||||
shadow = new View(context);
|
||||
shadow.setAlpha(0.0f);
|
||||
shadow.setVisibility(View.INVISIBLE);
|
||||
shadow.setTag(1);
|
||||
containerView.addView(shadow, frameLayoutParams);
|
||||
|
||||
listView = new RecyclerListView(context) {
|
||||
|
||||
int lastH;
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
if (ignoreLayout) {
|
||||
return;
|
||||
}
|
||||
super.requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthSpec, int heightSpec) {
|
||||
if (lastH != MeasureSpec.getSize(heightSpec)) {
|
||||
lastH = MeasureSpec.getSize(heightSpec);
|
||||
ignoreLayout = true;
|
||||
listView.setPadding(0, 0, 0, 0);
|
||||
ignoreLayout = false;
|
||||
|
||||
measure(widthSpec, View.MeasureSpec.makeMeasureSpec(heightSpec, MeasureSpec.AT_MOST));
|
||||
int contentSize = getMeasuredHeight();
|
||||
|
||||
int padding = (int) (lastH / 5f * 2f);
|
||||
if (padding < lastH - contentSize + AndroidUtilities.dp(60)) {
|
||||
padding = lastH - contentSize;
|
||||
}
|
||||
ignoreLayout = true;
|
||||
listView.setPadding(0, padding, 0, 0);
|
||||
ignoreLayout = false;
|
||||
|
||||
measure(widthSpec, View.MeasureSpec.makeMeasureSpec(heightSpec, MeasureSpec.AT_MOST));
|
||||
}
|
||||
|
||||
super.onMeasure(widthSpec, heightSpec);
|
||||
}
|
||||
};
|
||||
listView.setTag(14);
|
||||
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
|
||||
listView.setLayoutManager(layoutManager);
|
||||
listView.setAdapter(adapter = new Adapter());
|
||||
listView.setVerticalScrollBarEnabled(false);
|
||||
listView.setClipToPadding(false);
|
||||
listView.setNestedScrollingEnabled(true);
|
||||
listView.setOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
updateLayout();
|
||||
if (hasMore && !usersLoading) {
|
||||
int lastPosition = layoutManager.findLastVisibleItemPosition();
|
||||
if (rowCount - lastPosition < 10) {
|
||||
loadUsers();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
listView.setOnItemClickListener(new RecyclerListView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(View view, int position) {
|
||||
if (position == creatorRow || (position >= usersStartRow && position < usersEndRow)) {
|
||||
TLRPC.User user;
|
||||
if (position == creatorRow) {
|
||||
user = users.get(invite.admin_id);
|
||||
} else {
|
||||
TLRPC.TL_chatInviteImporter invitedUser = invitedUsers.get(position - usersStartRow);
|
||||
user = users.get(invitedUser.user_id);
|
||||
}
|
||||
if (user != null) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("user_id", user.id);
|
||||
MessagesController.getInstance(UserConfig.selectedAccount).putUser(user, false);
|
||||
ProfileActivity profileActivity = new ProfileActivity(bundle);
|
||||
fragment.presentFragment(profileActivity);
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
containerView.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, permanent ? 0 : 48, 0, 0));
|
||||
|
||||
if (!permanent) {
|
||||
titleTextView = new TextView(context);
|
||||
titleTextView.setLines(1);
|
||||
titleTextView.setSingleLine(true);
|
||||
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
|
||||
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
titleTextView.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
|
||||
titleTextView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
titleTextView.setText(invite.revoked ? LocaleController.getString("RevokedLink", R.string.RevokedLink) : LocaleController.getString("InviteLink", R.string.InviteLink));
|
||||
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
containerView.addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 50, Gravity.LEFT | Gravity.TOP, 0, 0, 40, 0));
|
||||
}
|
||||
|
||||
updateRows();
|
||||
loadUsers();
|
||||
if (users.get(invite.admin_id) == null) {
|
||||
loadCreator();
|
||||
}
|
||||
|
||||
updateColors();
|
||||
}
|
||||
|
||||
public void updateColors() {
|
||||
if (titleTextView != null) {
|
||||
titleTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
|
||||
titleTextView.setLinkTextColor(Theme.getColor(Theme.key_dialogTextLink));
|
||||
titleTextView.setHighlightColor(Theme.getColor(Theme.key_dialogLinkSelection));
|
||||
}
|
||||
listView.setGlowColor(Theme.getColor(Theme.key_dialogScrollGlow));
|
||||
shadow.setBackgroundColor(Theme.getColor(Theme.key_dialogShadowLine));
|
||||
setBackgroundColor(Theme.getColor(Theme.key_dialogBackground));
|
||||
|
||||
|
||||
int count = listView.getHiddenChildCount();
|
||||
|
||||
for (int i = 0; i < listView.getChildCount(); i++) {
|
||||
updateColorForView(listView.getChildAt(i));
|
||||
}
|
||||
for (int a = 0; a < count; a++) {
|
||||
updateColorForView(listView.getHiddenChildAt(a));
|
||||
}
|
||||
count = listView.getCachedChildCount();
|
||||
for (int a = 0; a < count; a++) {
|
||||
updateColorForView(listView.getCachedChildAt(a));
|
||||
}
|
||||
count = listView.getAttachedScrapChildCount();
|
||||
for (int a = 0; a < count; a++) {
|
||||
updateColorForView(listView.getAttachedScrapChildAt(a));
|
||||
}
|
||||
containerView.invalidate();
|
||||
}
|
||||
|
||||
private void updateColorForView(View view) {
|
||||
if (view instanceof HeaderCell) {
|
||||
((HeaderCell) view).getTextView().setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueHeader));
|
||||
} else if (view instanceof LinkActionView){
|
||||
((LinkActionView) view).updateColors();
|
||||
} else if (view instanceof TextInfoPrivacyCell) {
|
||||
CombinedDrawable combinedDrawable = new CombinedDrawable(new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray)), Theme.getThemedDrawable(view.getContext(), R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
|
||||
combinedDrawable.setFullsize(true);
|
||||
view.setBackground(combinedDrawable);
|
||||
((TextInfoPrivacyCell) view).setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText4));
|
||||
} else if (view instanceof UserCell) {
|
||||
((UserCell) view).update(0);
|
||||
}
|
||||
RecyclerView.ViewHolder holder = listView.getChildViewHolder(view);
|
||||
if (holder != null){
|
||||
if (holder.getItemViewType() == 7) {
|
||||
Drawable shadowDrawable = Theme.getThemedDrawable(view.getContext(), R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow);
|
||||
Drawable background = new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
CombinedDrawable combinedDrawable = new CombinedDrawable(background, shadowDrawable, 0, 0);
|
||||
combinedDrawable.setFullsize(true);
|
||||
view.setBackgroundDrawable(combinedDrawable);
|
||||
} else if (holder.getItemViewType() == 2) {
|
||||
Drawable shadowDrawable = Theme.getThemedDrawable(view.getContext(), R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow);
|
||||
Drawable background = new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
CombinedDrawable combinedDrawable = new CombinedDrawable(background, shadowDrawable, 0, 0);
|
||||
combinedDrawable.setFullsize(true);
|
||||
view.setBackgroundDrawable(combinedDrawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadCreator() {
|
||||
TLRPC.TL_users_getUsers req = new TLRPC.TL_users_getUsers();
|
||||
req.id.add(MessagesController.getInstance(UserConfig.selectedAccount).getInputUser(invite.admin_id));
|
||||
ConnectionsManager.getInstance(UserConfig.selectedAccount).sendRequest(req, (response, error) -> {
|
||||
AndroidUtilities.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (error == null) {
|
||||
TLRPC.Vector vector = (TLRPC.Vector) response;
|
||||
TLRPC.User user = (TLRPC.User) vector.objects.get(0);
|
||||
users.put(invite.admin_id, user);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDismissWithSwipe() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateRows() {
|
||||
rowCount = 0;
|
||||
dividerRow = -1;
|
||||
divider2Row = -1;
|
||||
usersHeaderRow = -1;
|
||||
usersStartRow = -1;
|
||||
usersEndRow = -1;
|
||||
emptyView2 = -1;
|
||||
linkActionRow = -1;
|
||||
linkInfoRow = -1;
|
||||
|
||||
|
||||
if (!permanent) {
|
||||
linkActionRow = rowCount++;
|
||||
linkInfoRow = rowCount++;
|
||||
}
|
||||
creatorHeaderRow = rowCount++;
|
||||
creatorRow = rowCount++;
|
||||
emptyView = rowCount++;
|
||||
|
||||
if (invite.usage > 0) {
|
||||
dividerRow = rowCount++;
|
||||
usersHeaderRow = rowCount++;
|
||||
if (!invitedUsers.isEmpty()) {
|
||||
usersStartRow = rowCount;
|
||||
rowCount += invitedUsers.size();
|
||||
usersEndRow = rowCount;
|
||||
} else {
|
||||
loadingRow = rowCount++;
|
||||
}
|
||||
emptyView2 = rowCount++;
|
||||
}
|
||||
divider2Row = rowCount++;
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private class Adapter extends RecyclerListView.SelectionAdapter {
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == creatorHeaderRow) {
|
||||
return 0;
|
||||
} else if (position == creatorRow || position >= usersStartRow && position < usersEndRow) {
|
||||
return 1;
|
||||
} else if (position == dividerRow) {
|
||||
return 2;
|
||||
} else if (position == linkActionRow) {
|
||||
return 3;
|
||||
} else if (position == linkInfoRow) {
|
||||
return 4;
|
||||
} else if (position == loadingRow) {
|
||||
return 5;
|
||||
} else if (position == emptyView || position == emptyView2) {
|
||||
return 6;
|
||||
} else if (position == divider2Row) {
|
||||
return 7;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view;
|
||||
Context context = parent.getContext();
|
||||
switch (viewType) {
|
||||
default:
|
||||
case 0:
|
||||
view = new HeaderCell(context);
|
||||
break;
|
||||
case 1:
|
||||
view = new UserCell(context, 12, 0, true);
|
||||
break;
|
||||
case 2:
|
||||
view = new ShadowSectionCell(context, 12, Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
break;
|
||||
case 3:
|
||||
LinkActionView linkActionView = new LinkActionView(context, fragment, InviteLinkBottomSheet.this, chatId, false);
|
||||
view = linkActionView;
|
||||
linkActionView.setDelegate(new LinkActionView.Delegate() {
|
||||
@Override
|
||||
public void revokeLink() {
|
||||
if (fragment instanceof ManageLinksActivity) {
|
||||
((ManageLinksActivity) fragment).revokeLink(invite);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editLink() {
|
||||
if (fragment instanceof ManageLinksActivity) {
|
||||
((ManageLinksActivity) fragment).editLink(invite);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLink() {
|
||||
if (fragment instanceof ManageLinksActivity) {
|
||||
((ManageLinksActivity) fragment).deleteLink(invite);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
break;
|
||||
case 4:
|
||||
view = new TextInfoPrivacyCell(context);
|
||||
CombinedDrawable combinedDrawable = new CombinedDrawable(new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray)), Theme.getThemedDrawable(context, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
|
||||
combinedDrawable.setFullsize(true);
|
||||
view.setBackground(combinedDrawable);
|
||||
break;
|
||||
case 5:
|
||||
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(context);
|
||||
flickerLoadingView.setIsSingleCell(true);
|
||||
flickerLoadingView.setViewType(FlickerLoadingView.USERS2_TYPE);
|
||||
flickerLoadingView.showDate(false);
|
||||
view = flickerLoadingView;
|
||||
break;
|
||||
case 6:
|
||||
view = new View(context) {
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(5), MeasureSpec.EXACTLY));
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 7:
|
||||
view = new ShadowSectionCell(context, 12);
|
||||
Drawable shadowDrawable = Theme.getThemedDrawable(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow);
|
||||
Drawable background = new ColorDrawable(Theme.getColor(Theme.key_windowBackgroundGray));
|
||||
combinedDrawable = new CombinedDrawable(background, shadowDrawable, 0, 0);
|
||||
combinedDrawable.setFullsize(true);
|
||||
view.setBackgroundDrawable(combinedDrawable);
|
||||
break;
|
||||
}
|
||||
view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
return new RecyclerListView.Holder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
case 0:
|
||||
HeaderCell headerCell = (HeaderCell) holder.itemView;
|
||||
if (position == creatorHeaderRow) {
|
||||
headerCell.setText(LocaleController.getString("LinkCreatedeBy", R.string.LinkCreatedeBy));
|
||||
} else if (position == usersHeaderRow) {
|
||||
headerCell.setText(LocaleController.formatPluralString("PeopleJoined", invite.usage));
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
UserCell userCell = (UserCell) holder.itemView;
|
||||
TLRPC.User user;
|
||||
String role = null;
|
||||
String status = null;
|
||||
if (position == creatorRow) {
|
||||
user = users.get(invite.admin_id);
|
||||
if (user != null) {
|
||||
status = LocaleController.formatDateAudio(invite.date, false);
|
||||
}
|
||||
if (info != null && user != null) {
|
||||
for (int i = 0; i < info.participants.participants.size(); i++) {
|
||||
if (info.participants.participants.get(i).user_id == user.id) {
|
||||
TLRPC.ChatParticipant part = info.participants.participants.get(i);
|
||||
|
||||
if (part instanceof TLRPC.TL_chatChannelParticipant) {
|
||||
TLRPC.ChannelParticipant channelParticipant = ((TLRPC.TL_chatChannelParticipant) part).channelParticipant;
|
||||
if (!TextUtils.isEmpty(channelParticipant.rank)) {
|
||||
role = channelParticipant.rank;
|
||||
} else {
|
||||
if (channelParticipant instanceof TLRPC.TL_channelParticipantCreator) {
|
||||
role = LocaleController.getString("ChannelCreator", R.string.ChannelCreator);
|
||||
} else if (channelParticipant instanceof TLRPC.TL_channelParticipantAdmin) {
|
||||
role = LocaleController.getString("ChannelAdmin", R.string.ChannelAdmin);
|
||||
} else {
|
||||
role = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (part instanceof TLRPC.TL_chatParticipantCreator) {
|
||||
role = LocaleController.getString("ChannelCreator", R.string.ChannelCreator);
|
||||
} else if (part instanceof TLRPC.TL_chatParticipantAdmin) {
|
||||
role = LocaleController.getString("ChannelAdmin", R.string.ChannelAdmin);
|
||||
} else {
|
||||
role = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
TLRPC.TL_chatInviteImporter invitedUser = invitedUsers.get(position - usersStartRow);
|
||||
user = users.get(invitedUser.user_id);
|
||||
}
|
||||
userCell.setAdminRole(role);
|
||||
userCell.setData(user, null, status, 0, false);
|
||||
break;
|
||||
case 3:
|
||||
LinkActionView actionView = (LinkActionView) holder.itemView;
|
||||
actionView.setUsers(0, null);
|
||||
actionView.setLink(invite.link);
|
||||
actionView.setRevoke(invite.revoked);
|
||||
break;
|
||||
case 4:
|
||||
TextInfoPrivacyCell privacyCell = (TextInfoPrivacyCell) holder.itemView;
|
||||
if (invite.revoked) {
|
||||
privacyCell.setText(LocaleController.getString("LinkIsNoActive", R.string.LinkIsNoActive));
|
||||
} else if (invite.expired) {
|
||||
privacyCell.setText(LocaleController.getString("LinkIsExpired", R.string.LinkIsExpired));
|
||||
} else if (invite.expire_date > 0) {
|
||||
privacyCell.setText(LocaleController.formatString("LinkExpiresIn", R.string.LinkExpiresIn, LocaleController.formatDateAudio(invite.expire_date, false)));
|
||||
} else {
|
||||
privacyCell.setText(null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(RecyclerView.ViewHolder holder) {
|
||||
int position = holder.getAdapterPosition();
|
||||
if (position == creatorRow || (position >= usersStartRow && position < usersEndRow)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLayout() {
|
||||
if (listView.getChildCount() <= 0) {
|
||||
listView.setTopGlowOffset(scrollOffsetY = listView.getPaddingTop());
|
||||
titleTextView.setTranslationY(scrollOffsetY);
|
||||
shadow.setTranslationY(scrollOffsetY);
|
||||
containerView.invalidate();
|
||||
return;
|
||||
}
|
||||
View child = listView.getChildAt(0);
|
||||
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findContainingViewHolder(child);
|
||||
int top = child.getTop();
|
||||
int newOffset = 0;
|
||||
if (top >= 0 && holder != null && holder.getAdapterPosition() == 0) {
|
||||
newOffset = top;
|
||||
runShadowAnimation(false);
|
||||
} else {
|
||||
runShadowAnimation(true);
|
||||
}
|
||||
if (scrollOffsetY != newOffset) {
|
||||
listView.setTopGlowOffset(scrollOffsetY = newOffset);
|
||||
if (titleTextView != null) {
|
||||
titleTextView.setTranslationY(scrollOffsetY);
|
||||
}
|
||||
shadow.setTranslationY(scrollOffsetY);
|
||||
containerView.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void runShadowAnimation(final boolean show) {
|
||||
if (show && shadow.getTag() != null || !show && shadow.getTag() == null) {
|
||||
shadow.setTag(show ? null : 1);
|
||||
if (show) {
|
||||
shadow.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (shadowAnimation != null) {
|
||||
shadowAnimation.cancel();
|
||||
}
|
||||
shadowAnimation = new AnimatorSet();
|
||||
shadowAnimation.playTogether(ObjectAnimator.ofFloat(shadow, View.ALPHA, show ? 1.0f : 0.0f));
|
||||
shadowAnimation.setDuration(150);
|
||||
shadowAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (shadowAnimation != null && shadowAnimation.equals(animation)) {
|
||||
if (!show) {
|
||||
shadow.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
shadowAnimation = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
if (shadowAnimation != null && shadowAnimation.equals(animation)) {
|
||||
shadowAnimation = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
shadowAnimation.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadUsers() {
|
||||
if (invite.usage <= 0 || usersLoading) {
|
||||
return;
|
||||
}
|
||||
TLRPC.TL_messages_getChatInviteImporters req = new TLRPC.TL_messages_getChatInviteImporters();
|
||||
req.link = invite.link;
|
||||
req.peer = MessagesController.getInstance(UserConfig.selectedAccount).getInputPeer(-chatId);
|
||||
if (invitedUsers.isEmpty()) {
|
||||
req.offset_user = new TLRPC.TL_inputUserEmpty();
|
||||
} else {
|
||||
TLRPC.TL_chatInviteImporter invitedUser = invitedUsers.get(invitedUsers.size() - 1);
|
||||
req.offset_user = MessagesController.getInstance(currentAccount).getInputUser(users.get(invitedUser.user_id));
|
||||
req.offset_date = invitedUser.date;
|
||||
}
|
||||
usersLoading = true;
|
||||
ConnectionsManager.getInstance(UserConfig.selectedAccount).sendRequest(req, (response, error) -> {
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (error == null) {
|
||||
TLRPC.TL_messages_chatInviteImporters inviteImporters = (TLRPC.TL_messages_chatInviteImporters) response;
|
||||
|
||||
invitedUsers.addAll(inviteImporters.importers);
|
||||
|
||||
for (int i = 0; i < inviteImporters.users.size(); i++) {
|
||||
TLRPC.User user = inviteImporters.users.get(i);
|
||||
users.put(user.id, user);
|
||||
}
|
||||
hasMore = invitedUsers.size() < inviteImporters.count;
|
||||
updateRows();
|
||||
}
|
||||
usersLoading = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@ package org.telegram.ui.Components;
|
|||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.view.View;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
|
@ -31,6 +32,8 @@ public class LineProgressView extends View {
|
|||
private static DecelerateInterpolator decelerateInterpolator;
|
||||
private static Paint progressPaint;
|
||||
|
||||
private RectF rect = new RectF();
|
||||
|
||||
public LineProgressView(Context context) {
|
||||
super(context);
|
||||
|
||||
|
@ -104,12 +107,14 @@ public class LineProgressView extends View {
|
|||
progressPaint.setColor(backColor);
|
||||
progressPaint.setAlpha((int) (255 * animatedAlphaValue));
|
||||
int start = (int) (getWidth() * animatedProgressValue);
|
||||
canvas.drawRect(start, 0, getWidth(), getHeight(), progressPaint);
|
||||
rect.set(0, 0, getWidth(), getHeight());
|
||||
canvas.drawRoundRect(rect, getHeight() / 2, getHeight() / 2, progressPaint);
|
||||
}
|
||||
|
||||
progressPaint.setColor(progressColor);
|
||||
progressPaint.setAlpha((int)(255 * animatedAlphaValue));
|
||||
canvas.drawRect(0, 0, getWidth() * animatedProgressValue, getHeight(), progressPaint);
|
||||
progressPaint.setAlpha((int) (255 * animatedAlphaValue));
|
||||
rect.set(0, 0, getWidth() * animatedProgressValue, getHeight());
|
||||
canvas.drawRoundRect(rect, getHeight() / 2, getHeight() / 2, progressPaint);
|
||||
updateAnimation();
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue