some
This commit is contained in:
parent
f48cc365e1
commit
3728863b63
23
package.json
23
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "telegram-invite-automation",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.0",
|
||||
"private": true,
|
||||
"description": "Automated user parsing and invites for Telegram groups",
|
||||
"main": "src/main/index.js",
|
||||
@ -8,16 +8,16 @@
|
||||
"scripts": {
|
||||
"dev": "concurrently -k \"vite\" \"wait-on http://127.0.0.1:5173 && electron .\"",
|
||||
"start": "electron .",
|
||||
"build": "vite build && electron-builder",
|
||||
"build:win": "vite build && electron-builder --win",
|
||||
"build:win:x64": "vite build && electron-builder --win --x64",
|
||||
"build:win:x64:installer": "vite build && electron-builder --win --x64 --config.win.target=nsis",
|
||||
"build:win:x64:portable": "vite build && electron-builder --win --x64 --config.win.target=portable",
|
||||
"build": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder",
|
||||
"build:win": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder --win",
|
||||
"build:win:x64": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder --win --x64",
|
||||
"build:win:x64:installer": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder --win --x64 --config.win.target=nsis",
|
||||
"build:win:x64:portable": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder --win --x64 --config.win.target=portable",
|
||||
"build:win:x64:portable:zip": "npm run build:win:x64:portable && zip -j -o dist/release/Telegram-Invite-Automation-win-portable-x64.zip dist/release/Telegram-Invite-Automation-win-x64-*.exe",
|
||||
"build:mac": "vite build && electron-builder --mac",
|
||||
"build:all": "vite build && electron-builder --win --mac",
|
||||
"build:linux": "vite build && electron-builder --linux",
|
||||
"dist": "vite build && electron-builder",
|
||||
"build:mac": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder --mac",
|
||||
"build:all": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder --win --mac",
|
||||
"build:linux": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder --linux",
|
||||
"dist": "NODE_OPTIONS=--no-warnings vite build && NODE_OPTIONS=--no-warnings electron-builder",
|
||||
"build:converter:mac": "bash scripts/build-converter.sh",
|
||||
"build:converter:win": "powershell -ExecutionPolicy Bypass -File scripts/build-converter.ps1"
|
||||
},
|
||||
@ -29,6 +29,7 @@
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/notarize": "^2.2.0",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"concurrently": "^8.2.2",
|
||||
"electron": "^29.1.0",
|
||||
@ -69,12 +70,14 @@
|
||||
"asarUnpack": [
|
||||
"**/*.node"
|
||||
],
|
||||
"afterSign": "scripts/notarize.js",
|
||||
"electronLanguages": [
|
||||
"ru",
|
||||
"en-US"
|
||||
],
|
||||
"mac": {
|
||||
"category": "public.app-category.productivity",
|
||||
"hardenedRuntime": true,
|
||||
"target": [
|
||||
"dmg"
|
||||
],
|
||||
|
||||
28
scripts/notarize.js
Normal file
28
scripts/notarize.js
Normal file
@ -0,0 +1,28 @@
|
||||
const path = require("path");
|
||||
const { notarize } = require("@electron/notarize");
|
||||
|
||||
exports.default = async function notarizing(context) {
|
||||
const { electronPlatformName, appOutDir } = context;
|
||||
if (electronPlatformName !== "darwin") return;
|
||||
|
||||
const appleId = process.env.APPLE_ID;
|
||||
const appleIdPassword = process.env.APPLE_ID_PASSWORD;
|
||||
const teamId = process.env.APPLE_TEAM_ID;
|
||||
|
||||
if (!appleId || !appleIdPassword || !teamId) {
|
||||
console.log("[notarize] Skipped: APPLE_ID / APPLE_ID_PASSWORD / APPLE_TEAM_ID not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
const appName = context.packager.appInfo.productFilename;
|
||||
const appPath = path.join(appOutDir, `${appName}.app`);
|
||||
|
||||
console.log(`[notarize] Notarizing ${appPath}`);
|
||||
await notarize({
|
||||
tool: "notarytool",
|
||||
appPath,
|
||||
appleId,
|
||||
appleIdPassword,
|
||||
teamId
|
||||
});
|
||||
};
|
||||
@ -235,8 +235,10 @@ export default function App() {
|
||||
pushStep("Проверка прав инвайта", okCount > 0 ? "ok" : "warn", `OK: ${okCount} / ${inviteAccessStatus.length}`);
|
||||
}
|
||||
pushStep("Очередь", queueStats.total > 0 ? "ok" : "warn", `В очереди: ${queueStats.total}`);
|
||||
const intervalOk = Number(taskForm.minInterval) <= Number(taskForm.maxInterval);
|
||||
pushStep("Интервалы и лимиты", intervalOk ? "ok" : "warn", `Мин: ${taskForm.minInterval} · Макс: ${taskForm.maxInterval}`);
|
||||
const minInterval = Number(taskForm.minIntervalMinutes || 0);
|
||||
const maxInterval = Number(taskForm.maxIntervalMinutes || 0);
|
||||
const intervalOk = minInterval > 0 && maxInterval > 0 && minInterval <= maxInterval;
|
||||
pushStep("Интервалы и лимиты", intervalOk ? "ok" : "warn", `Мин: ${minInterval || "—"} · Макс: ${maxInterval || "—"}`);
|
||||
if (taskForm.inviteViaAdmins) {
|
||||
pushStep("Инвайт через админов", taskForm.inviteAdminMasterId ? "ok" : "warn", taskForm.inviteAdminMasterId ? "Мастер-админ выбран" : "Не выбран мастер-админ");
|
||||
} else {
|
||||
@ -552,7 +554,9 @@ export default function App() {
|
||||
loadAccountAssignments,
|
||||
showNotification,
|
||||
setTaskNotice,
|
||||
setAccounts
|
||||
setAccounts,
|
||||
membershipStatus,
|
||||
refreshMembership
|
||||
});
|
||||
const { applyTaskPreset } = useTaskPresets({
|
||||
hasSelectedTask,
|
||||
@ -883,8 +887,6 @@ export default function App() {
|
||||
accessStatus,
|
||||
roleSummary,
|
||||
mutualContactDiagnostics,
|
||||
accountById,
|
||||
formatAccountLabel,
|
||||
accountEvents,
|
||||
clearAccountEvents,
|
||||
onSettingsChange,
|
||||
|
||||
@ -11,7 +11,9 @@ export default function useAccountManagement({
|
||||
loadAccountAssignments,
|
||||
showNotification,
|
||||
setTaskNotice,
|
||||
setAccounts
|
||||
setAccounts,
|
||||
membershipStatus,
|
||||
refreshMembership
|
||||
}) {
|
||||
const persistAccountRoles = async (next) => {
|
||||
if (!window.api || selectedTaskId == null) return;
|
||||
@ -76,7 +78,7 @@ export default function useAccountManagement({
|
||||
persistAccountRoles(next);
|
||||
};
|
||||
|
||||
const applyRolePreset = (type) => {
|
||||
const applyRolePreset = async (type) => {
|
||||
if (!hasSelectedTask) return;
|
||||
const availableIds = selectedAccountIds.length
|
||||
? selectedAccountIds
|
||||
@ -116,13 +118,64 @@ export default function useAccountManagement({
|
||||
const existing = taskAccountRoles[id] || {};
|
||||
next[id] = { monitor: false, invite: false, confirm: true, inviteLimit: existing.inviteLimit || 0 };
|
||||
});
|
||||
if (monitorIds.length < monitorCount) {
|
||||
if (typeof refreshMembership === "function") {
|
||||
await refreshMembership("roles");
|
||||
}
|
||||
const monitorRoleIds = Object.entries(next)
|
||||
.filter(([, roles]) => roles && roles.monitor)
|
||||
.map(([id]) => Number(id));
|
||||
const monitorInCompetitors = monitorRoleIds.filter((id) => {
|
||||
const membership = membershipStatus && membershipStatus[id];
|
||||
if (!membership) return false;
|
||||
const total = Number(membership.competitorTotal || 0);
|
||||
return total > 0 && Number(membership.competitorCount || 0) > 0;
|
||||
});
|
||||
if (!monitorRoleIds.length) {
|
||||
showNotification("Нет бота мониторинга. Назначьте роль мониторинга.", "error");
|
||||
} else if (!monitorInCompetitors.length) {
|
||||
showNotification("Нет бота мониторинга в группах конкурентов. Введите бота в конкурентов или включите авто‑вступление.", "error");
|
||||
} else {
|
||||
showNotification("Не хватает аккаунтов для роли мониторинга.", "error");
|
||||
}
|
||||
}
|
||||
if (inviteIds.length < inviteCount) {
|
||||
if (typeof refreshMembership === "function") {
|
||||
await refreshMembership("roles");
|
||||
}
|
||||
const inviteRoleIds = Object.entries(next)
|
||||
.filter(([, roles]) => roles && roles.invite)
|
||||
.map(([id]) => Number(id));
|
||||
const inviteInOurGroup = inviteRoleIds.filter(
|
||||
(id) => membershipStatus && membershipStatus[id] && membershipStatus[id].ourGroupMember
|
||||
);
|
||||
if (!inviteRoleIds.length) {
|
||||
showNotification("Нет инвайт‑бота. Назначьте роль инвайта.", "error");
|
||||
} else if (!inviteInOurGroup.length) {
|
||||
showNotification("Нет инвайт‑бота в нашей группе. Введите бота в нашу группу или включите авто‑вступление.", "error");
|
||||
} else {
|
||||
showNotification("Не хватает аккаунтов для роли инвайта.", "error");
|
||||
}
|
||||
}
|
||||
if (taskForm.separateConfirmRoles && confirmIds.length < confirmCount) {
|
||||
if (typeof refreshMembership === "function") {
|
||||
await refreshMembership("roles");
|
||||
}
|
||||
const confirmRoleIds = Object.entries(next)
|
||||
.filter(([, roles]) => roles && roles.confirm)
|
||||
.map(([id]) => Number(id));
|
||||
const confirmInOurGroup = confirmRoleIds.filter(
|
||||
(id) => membershipStatus && membershipStatus[id] && membershipStatus[id].ourGroupMember
|
||||
);
|
||||
if (!confirmRoleIds.length) {
|
||||
showNotification("Нет подтверждающего бота. Назначьте роль подтверждения.", "error");
|
||||
} else if (!confirmInOurGroup.length) {
|
||||
showNotification("Нет подтверждающего бота в нашей группе. Введите бота в нашу группу или включите авто‑вступление.", "error");
|
||||
} else {
|
||||
showNotification("Не хватает аккаунтов для роли подтверждения.", "error");
|
||||
}
|
||||
}
|
||||
}
|
||||
const ids = Object.keys(next).map((id) => Number(id));
|
||||
setTaskAccountRoles(next);
|
||||
setSelectedAccountIds(ids);
|
||||
|
||||
@ -108,8 +108,6 @@ export default function useAppTabGroups({
|
||||
accessStatus,
|
||||
roleSummary,
|
||||
mutualContactDiagnostics,
|
||||
accountById,
|
||||
formatAccountLabel,
|
||||
accountEvents,
|
||||
clearAccountEvents,
|
||||
onSettingsChange,
|
||||
|
||||
@ -99,14 +99,6 @@ export default function useTabProps(
|
||||
setConfirmPage,
|
||||
confirmPageCount,
|
||||
pagedConfirmQueue,
|
||||
queueItems,
|
||||
queueStats,
|
||||
queueSearch,
|
||||
setQueueSearch,
|
||||
queuePage,
|
||||
setQueuePage,
|
||||
queuePageCount,
|
||||
pagedQueue,
|
||||
clearConfirmQueue,
|
||||
auditSearch,
|
||||
setAuditSearch,
|
||||
@ -122,9 +114,7 @@ export default function useTabProps(
|
||||
selectedTask,
|
||||
accessStatus,
|
||||
roleSummary,
|
||||
mutualContactDiagnostics,
|
||||
accountById,
|
||||
formatAccountLabel
|
||||
mutualContactDiagnostics
|
||||
} = logsTab;
|
||||
const {
|
||||
queueStats,
|
||||
@ -242,14 +232,6 @@ export default function useTabProps(
|
||||
setConfirmPage,
|
||||
confirmPageCount,
|
||||
pagedConfirmQueue,
|
||||
queueItems,
|
||||
queueStats,
|
||||
queueSearch,
|
||||
setQueueSearch,
|
||||
queuePage,
|
||||
setQueuePage,
|
||||
queuePageCount,
|
||||
pagedQueue,
|
||||
clearConfirmQueue,
|
||||
auditSearch,
|
||||
setAuditSearch,
|
||||
|
||||
@ -1962,6 +1962,38 @@ label .hint {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.log-table {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.log-head,
|
||||
.log-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 1.6fr 1.4fr 0.6fr 0.8fr;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.log-head {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.log-row {
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.log-empty {
|
||||
font-size: 13px;
|
||||
color: #64748b;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.log-result {
|
||||
font-size: 13px;
|
||||
color: #1f2937;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user