mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Fix Cursor rules files.
This commit is contained in:
parent
57d24d0fbf
commit
1d2f713673
4 changed files with 44 additions and 24 deletions
|
@ -1,8 +1,13 @@
|
|||
---
|
||||
description: For tasks requiring sending Telegram server API requests or working with generated API types.
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
# Telegram Desktop API Usage
|
||||
|
||||
## API Schema
|
||||
|
||||
The API definitions are described using [TL Language](https://core.telegram.org/mtproto/TL) in two main schema files:
|
||||
The API definitions are described using [TL Language]\(https:/core.telegram.org/mtproto/TL) in two main schema files:
|
||||
|
||||
1. **`Telegram/SourceFiles/mtproto/scheme/mtproto.tl`**
|
||||
* Defines the core MTProto protocol types and methods used for basic communication, encryption, authorization, service messages, etc.
|
||||
|
@ -39,7 +44,7 @@ api().request(MTPnamespace_MethodName(
|
|||
MTP_long(randomId),
|
||||
// ... other arguments matching the TL definition
|
||||
MTP_vector<MTPMessageEntity>() // Example for a vector argument
|
||||
)).done([=](const MTPResponseType &result) {
|
||||
)).done([=]\(const MTPResponseType &result) {
|
||||
// Handle the successful response (result).
|
||||
// 'result' will be of the C++ type corresponding to the TL type
|
||||
// specified after the '=' in the api.tl method definition.
|
||||
|
@ -47,9 +52,9 @@ api().request(MTPnamespace_MethodName(
|
|||
|
||||
// 1. Multiple Constructors (e.g., User = User | UserEmpty):
|
||||
// Use .match() with lambdas for each constructor:
|
||||
result.match([&](const MTPDuser &data) {
|
||||
result.match([&]\(const MTPDuser &data) {
|
||||
/* use data.vfirst_name().v, etc. */
|
||||
}, [&](const MTPDuserEmpty &data) {
|
||||
}, [&]\(const MTPDuserEmpty &data) {
|
||||
/* handle empty user */
|
||||
});
|
||||
|
||||
|
@ -64,7 +69,7 @@ api().request(MTPnamespace_MethodName(
|
|||
|
||||
// 2. Single Constructor (e.g., Messages = messages { msgs: vector<Message> }):
|
||||
// Use .match() with a single lambda:
|
||||
result.match([&](const MTPDmessages &data) { /* use data.vmessages().v */ });
|
||||
result.match([&]\(const MTPDmessages &data) { /* use data.vmessages().v */ });
|
||||
|
||||
// Or check the type explicitly and use the constructor getter:
|
||||
if (result.type() == mtpc_messages) {
|
||||
|
@ -76,7 +81,7 @@ api().request(MTPnamespace_MethodName(
|
|||
const auto &data = result.data(); // Only works for single-constructor types!
|
||||
// use data.vmessages().v
|
||||
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
}).fail([=]\(const MTP::Error &error) {
|
||||
// Handle the API error (error).
|
||||
// 'error' is an MTP::Error object containing the error code (error.type())
|
||||
// and description (error.description()). Check for specific error strings.
|
||||
|
@ -93,8 +98,8 @@ api().request(MTPnamespace_MethodName(
|
|||
* Always refer to `Telegram/SourceFiles/mtproto/scheme/api.tl` for the correct method names, parameters (names and types), and response types.
|
||||
* Use the generated `MTP...` types/classes for request parameters (e.g., `MTP_int`, `MTP_string`, `MTP_bool`, `MTP_vector`, `MTPInputUser`, etc.) and response handling.
|
||||
* The `.done()` lambda receives the specific C++ `MTP...` type corresponding to the TL return type.
|
||||
* For types with **multiple constructors** (e.g., `User = User | UserEmpty`), use `result.match([&](const MTPDuser &d){ ... }, [&](const MTPDuserEmpty &d){ ... })` to handle each case, or check `result.type() == mtpc_user` / `mtpc_userEmpty` and call the specific `result.c_user()` / `result.c_userEmpty()` getter (which asserts on type mismatch).
|
||||
* For types with a **single constructor** (e.g., `Messages = messages{...}`), you can use `result.match([&](const MTPDmessages &d){ ... })` with one lambda, or check `type()` and call `c_messages()`, or use the shortcut `result.data()` to access the fields directly.
|
||||
* For types with **multiple constructors** (e.g., `User = User | UserEmpty`), use `result.match([&]\(const MTPDuser &d){ ... }, [&]\(const MTPDuserEmpty &d){ ... })` to handle each case, or check `result.type() == mtpc_user` / `mtpc_userEmpty` and call the specific `result.c_user()` / `result.c_userEmpty()` getter (which asserts on type mismatch).
|
||||
* For types with a **single constructor** (e.g., `Messages = messages{...}`), you can use `result.match([&]\(const MTPDmessages &d){ ... })` with one lambda, or check `type()` and call `c_messages()`, or use the shortcut `result.data()` to access the fields directly.
|
||||
* The `.fail()` lambda receives an `MTP::Error` object. Check `error.type()` against known error strings (often defined as constants or using `u"..."_q` literals).
|
||||
* Directly construct the `MTPnamespace_MethodName(...)` object inside `request()`.
|
||||
* Include `.handleFloodErrors()` before `.send()` for standard flood wait handling.
|
||||
* Include `.handleFloodErrors()` before `.send()` for standard flood wait handling.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
---
|
||||
description: For tasks requiring changing or adding user facing phrases and text parts.
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
# Telegram Desktop Localization
|
||||
|
||||
## Coding Style Note
|
||||
|
@ -156,4 +161,4 @@ auto messageProducer = tr::lng_user_posted_photo( // Type: rpl::producer<TextWit
|
|||
* Immediate: Pass `int` or `float64`.
|
||||
* Reactive: Pass `rpl::producer<float64>`, typically by converting an `int` producer using `| tr::to_count()`.
|
||||
* Optional projector function as the last argument modifies the output type and required placeholder types.
|
||||
* Actual translations are loaded at runtime from the API.
|
||||
* Actual translations are loaded at runtime from the API.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
# RPL (Reactive Programming Library) Guide
|
||||
|
||||
## Coding Style Note
|
||||
|
@ -64,7 +69,7 @@ rpl::lifetime lifetime;
|
|||
// Counter is consumed here, use std::move if it's an l-value.
|
||||
std::move(
|
||||
counter
|
||||
) | rpl::start_with_next([=](int nextValue) {
|
||||
) | rpl::start_with_next([=]\(int nextValue) {
|
||||
// Process the next integer value emitted by the producer.
|
||||
qDebug() << "Received: " << nextValue;
|
||||
}, lifetime); // Pass the lifetime to manage the subscription.
|
||||
|
@ -77,7 +82,7 @@ std::move(
|
|||
auto counter2 = /* ... */; // Type: rpl::producer<int>
|
||||
rpl::lifetime subscriptionLifetime = std::move(
|
||||
counter2
|
||||
) | rpl::start_with_next([=](int nextValue) { /* ... */ });
|
||||
) | rpl::start_with_next([=]\(int nextValue) { /* ... */ });
|
||||
// The returned lifetime MUST be stored. If it's discarded immediately,
|
||||
// the subscription stops instantly.
|
||||
// `counter2` is also moved-from here.
|
||||
|
@ -93,7 +98,7 @@ rpl::lifetime lifetime;
|
|||
// If it's the only use, std::move(dataStream) would be preferred.
|
||||
rpl::duplicate(
|
||||
dataStream
|
||||
) | rpl::start_with_error([=](Error &&error) {
|
||||
) | rpl::start_with_error([=]\(Error &&error) {
|
||||
// Handle the error signaled by the producer.
|
||||
qDebug() << "Error: " << error.text();
|
||||
}, lifetime);
|
||||
|
@ -101,7 +106,7 @@ rpl::duplicate(
|
|||
// Using dataStream again, perhaps duplicated again or moved if last use.
|
||||
rpl::duplicate(
|
||||
dataStream
|
||||
) | rpl::start_with_done([=]() {
|
||||
) | rpl::start_with_done([=] {
|
||||
// Execute when the producer signals it's finished emitting values.
|
||||
qDebug() << "Stream finished.";
|
||||
}, lifetime);
|
||||
|
@ -110,9 +115,9 @@ rpl::duplicate(
|
|||
std::move(
|
||||
dataStream
|
||||
) | rpl::start_with_next_error_done(
|
||||
[=](QString &&value) { /* handle next value */ },
|
||||
[=](Error &&error) { /* handle error */ },
|
||||
[=]() { /* handle done */ },
|
||||
[=]\(QString &&value) { /* handle next value */ },
|
||||
[=]\(Error &&error) { /* handle error */ },
|
||||
[=] { /* handle done */ },
|
||||
lifetime);
|
||||
```
|
||||
|
||||
|
@ -164,7 +169,7 @@ You can combine multiple producers into one:
|
|||
// The lambda receives unpacked arguments, not the tuple itself.
|
||||
std::move(
|
||||
combined
|
||||
) | rpl::start_with_next([=](int count, const QString &text) {
|
||||
) | rpl::start_with_next([=]\(int count, const QString &text) {
|
||||
// No need for std::get<0>(latest), etc.
|
||||
qDebug() << "Combined: Count=" << count << ", Text=" << text;
|
||||
}, lifetime);
|
||||
|
@ -172,11 +177,11 @@ You can combine multiple producers into one:
|
|||
// This also works with map, filter, etc.
|
||||
std::move(
|
||||
combined
|
||||
) | rpl::filter([=](int count, const QString &text) {
|
||||
) | rpl::filter([=]\(int count, const QString &text) {
|
||||
return count > 0 && !text.isEmpty();
|
||||
}) | rpl::map([=](int count, const QString &text) {
|
||||
}) | rpl::map([=]\(int count, const QString &text) {
|
||||
return text.repeated(count);
|
||||
}) | rpl::start_with_next([=](const QString &result) {
|
||||
}) | rpl::start_with_next([=]\(const QString &result) {
|
||||
qDebug() << "Mapped & Filtered: " << result;
|
||||
}, lifetime);
|
||||
```
|
||||
|
@ -192,7 +197,7 @@ You can combine multiple producers into one:
|
|||
// Starting the merged producer consumes it.
|
||||
std::move(
|
||||
merged
|
||||
) | rpl::start_with_next([=](QString &&value) {
|
||||
) | rpl::start_with_next([=]\(QString &&value) {
|
||||
// Receives values from either sourceA or sourceB as they arrive.
|
||||
qDebug() << "Merged value: " << value;
|
||||
}, lifetime);
|
||||
|
@ -208,4 +213,4 @@ You can combine multiple producers into one:
|
|||
* Use `rpl::combine` or `rpl::merge` to combine streams.
|
||||
* When starting a chain (`std::move(producer) | rpl::map(...)`), explicitly move the initial producer.
|
||||
* These functions typically duplicate their input producers internally.
|
||||
* Starting a pipeline consumes the producer; use `
|
||||
* Starting a pipeline consumes the producer; use `
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
---
|
||||
description: For tasks requiring working with user facing UI components.
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
# Telegram Desktop UI Styling
|
||||
|
||||
## Style Definition Files
|
||||
|
@ -146,4 +151,4 @@ void MyWidget::paintEvent(QPaintEvent *e) {
|
|||
* Icons are defined inline using `name: icon{{ "path_stem", color }};` or `name: icon{ { "path1", c1 }, ... };` syntax, with optional path modifiers.
|
||||
* Code generation creates `struct` definitions in the `style` namespace for custom types and objects/structs in the `st` namespace for defined variables/groups.
|
||||
* Generated headers are in `styles/` with a `style_` prefix and must be included.
|
||||
* Access style properties via the generated `st::` objects (e.g., `st::primaryButton.height`, `st::chatInput.backgroundColor`).
|
||||
* Access style properties via the generated `st::` objects (e.g., `st::primaryButton.height`, `st::chatInput.backgroundColor`).
|
||||
|
|
Loading…
Add table
Reference in a new issue