Добавлен OTLP-провайдер, реализовано отбрасывание метрик и трейсов в observability + добавлен перезапуск nginx при пересборке контейнеров (ошибка, когда докер меняет адреса сервисов)

This commit is contained in:
mi
2026-07-29 15:15:40 +03:00
parent 3ed7239efa
commit 41e19005fb
43 changed files with 3016 additions and 83 deletions
@@ -9,6 +9,8 @@ import type { NotificationItem } from "../types";
import { ErrorNotice, Loading } from "../ui";
import { NotificationCard } from "./NotificationCard";
const CARD_GAP = spacing.sm;
export function NotificationCarousel({
authenticated,
autoplay = false,
@@ -27,6 +29,7 @@ export function NotificationCarousel({
const [hiddenGuestIds, setHiddenGuestIds] = useState<Set<string>>(() => new Set());
const window = useWindowDimensions();
const cardWidth = Math.max(0, Math.min(window.width, layout.maxWidth) - spacing.lg * 2);
const pageWidth = cardWidth + CARD_GAP;
const catalog = useQuery({
queryKey: notificationKeys.catalog,
queryFn: notificationApi.catalog,
@@ -57,6 +60,12 @@ export function NotificationCarousel({
list.current?.scrollToIndex({ index: next, animated: true });
};
const syncActiveIndex = (offset: number) => {
if (pageWidth <= 0) return;
const next = Math.min(data.length - 1, Math.max(0, Math.round(offset / pageWidth)));
setActiveIndex((current) => current === next ? current : next);
};
useEffect(() => {
if (!autoplay || data.length < 2) return;
const timer = setInterval(() => {
@@ -98,17 +107,15 @@ export function NotificationCarousel({
horizontal
data={data}
decelerationRate="fast"
pagingEnabled
snapToInterval={cardWidth}
disableIntervalMomentum
snapToInterval={pageWidth}
snapToAlignment="start"
getItemLayout={(_, index) => ({ length: cardWidth, offset: cardWidth * index, index })}
getItemLayout={(_, index) => ({ length: pageWidth, offset: pageWidth * index, index })}
ItemSeparatorComponent={() => <View style={local.separator} />}
keyExtractor={(item) => item.id}
style={local.carousel}
onMomentumScrollEnd={(event) => {
if (cardWidth > 0) {
setActiveIndex(Math.min(data.length - 1, Math.round(event.nativeEvent.contentOffset.x / cardWidth)));
}
}}
onScroll={(event) => syncActiveIndex(event.nativeEvent.contentOffset.x)}
scrollEventThrottle={16}
renderItem={({ item }) => (
<NotificationCard
disabled={hide.isPending}
@@ -139,6 +146,7 @@ export function NotificationCarousel({
const local = StyleSheet.create({
section: { paddingVertical: spacing.md },
carousel: { marginHorizontal: spacing.lg },
separator: { width: CARD_GAP },
state: { paddingHorizontal: spacing.lg, paddingVertical: spacing.md },
error: { paddingHorizontal: spacing.lg, paddingTop: spacing.sm },
});
@@ -48,7 +48,9 @@ export function QuickActions({ phone, authenticated = false }: { phone?: string
staleTime: 30_000,
refetchInterval: 30_000,
});
const hasUnreadMessages = (dialogs.data?.items ?? []).some((dialog) => (dialog.unread_count ?? 0) > 0);
const hasUnreadMessages = (dialogs.data?.items ?? []).some(
(dialog) => (dialog.unread_count ?? 0) > 0 || dialog.status === "waiting_for_client",
);
const call = () => {
if (phone) void Linking.openURL(`tel:${phone}`);