154 lines
4.0 KiB
JavaScript
154 lines
4.0 KiB
JavaScript
const TEAM_MEMBERS = [
|
||
{ id: "mazlum", name: "Mazlum", role: "Team Lead", icon: "🎩" },
|
||
{ id: "berkecan", name: "Berkecan", role: "Frontend Developer", icon: "💻" },
|
||
{ id: "simsar", name: "Simsar", role: "Backend Developer", icon: "⚙️" },
|
||
{ id: "aybuke", name: "Aybuke", role: "UI/UX Designer", icon: "🎨" },
|
||
{ id: "ive", name: "Ive", role: "iOS Developer", icon: "📱" },
|
||
{ id: "irgatov", name: "Irgatov", role: "Trainee", icon: "☕" }
|
||
];
|
||
|
||
function normalizeSpeaker(value) {
|
||
return String(value ?? "")
|
||
.normalize("NFD")
|
||
.replace(/[\u0300-\u036f]/g, "")
|
||
.toLowerCase();
|
||
}
|
||
|
||
const memberMap = new Map(TEAM_MEMBERS.map((member) => [normalizeSpeaker(member.name), member]));
|
||
|
||
function isNoiseLine(line) {
|
||
const trimmed = line.trim();
|
||
|
||
if (!trimmed) {
|
||
return true;
|
||
}
|
||
|
||
return [
|
||
/^╭|^╰|^│|^─/.test(trimmed),
|
||
/^❯/.test(trimmed),
|
||
/^⏵⏵/.test(trimmed),
|
||
/^⏺/.test(trimmed),
|
||
/^✻|^✽|^✳|^✢|^· /.test(trimmed),
|
||
/^Auth conflict:/i.test(trimmed),
|
||
/^unset ANTHROPIC_API_KEY/i.test(trimmed),
|
||
/^Tips for getting/i.test(trimmed),
|
||
/^Recent activity/i.test(trimmed),
|
||
/^No recent activity/i.test(trimmed),
|
||
/^glm-5/i.test(trimmed),
|
||
/^Org$/i.test(trimmed),
|
||
/^Press up to edit/i.test(trimmed),
|
||
/^Deliberating/i.test(trimmed),
|
||
/^Cultivating/i.test(trimmed),
|
||
/^Sistem yonlendirmesi:/i.test(trimmed),
|
||
/^Hedef kisi:/i.test(trimmed),
|
||
/^Yalnizca /i.test(trimmed),
|
||
/^Cevap zorunlu/i.test(trimmed),
|
||
/^Baska hicbir/i.test(trimmed),
|
||
/^Kullanici mesaji:/i.test(trimmed),
|
||
/^Takim ici /i.test(trimmed),
|
||
/^Her cevap /i.test(trimmed),
|
||
/^Etiketsiz cevap /i.test(trimmed),
|
||
/^Gecerli ornek:/i.test(trimmed),
|
||
/^Kullanici tek bir kisiye/i.test(trimmed),
|
||
/^Kullanici tum takima/i.test(trimmed),
|
||
/^Her ekip uyesi/i.test(trimmed),
|
||
/^Ilk cevap olarak/i.test(trimmed),
|
||
/^Bu ilk cevap/i.test(trimmed),
|
||
/^\(erkek\)|^\(disi\)/i.test(trimmed)
|
||
].some(Boolean);
|
||
}
|
||
|
||
function shouldBreakCurrentEntry(line) {
|
||
const trimmed = line.trim();
|
||
if (!trimmed) {
|
||
return false;
|
||
}
|
||
|
||
return [
|
||
isNoiseLine(trimmed),
|
||
/^[-=]{4,}$/.test(trimmed),
|
||
/^>/.test(trimmed),
|
||
/^Kullanici /i.test(trimmed),
|
||
/^Mazlum nasilsin\?/i.test(trimmed),
|
||
/^[A-Za-zÀ-ÿ]+,/.test(trimmed)
|
||
].some(Boolean);
|
||
}
|
||
|
||
function isContinuationLine(line) {
|
||
const trimmed = line.trim();
|
||
if (!trimmed) {
|
||
return true;
|
||
}
|
||
|
||
return [
|
||
/^[A-Za-zÀ-ÿ0-9ÇĞİÖŞÜçğıöşü"'`(]/.test(trimmed),
|
||
/^[.!?…]/.test(trimmed),
|
||
/^💪|^😊|^🚀|^☕|^🎨|^📱/.test(trimmed)
|
||
].some(Boolean);
|
||
}
|
||
|
||
function dedupeMessages(messages) {
|
||
const seen = new Set();
|
||
const result = [];
|
||
|
||
for (const message of messages) {
|
||
const key = `${message.speaker}::${message.text}`;
|
||
if (seen.has(key)) {
|
||
continue;
|
||
}
|
||
|
||
seen.add(key);
|
||
result.push(message);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
export function parseTeamFeed(chat) {
|
||
const entries = [];
|
||
let currentEntry = null;
|
||
|
||
for (const rawLine of String(chat ?? "").split("\n")) {
|
||
const line = rawLine.trim();
|
||
const speakerMatch = line.match(/^[•*\-⏺]?\s*([A-Za-zÀ-ÿ]+):\s*(.*)$/);
|
||
|
||
if (speakerMatch) {
|
||
const member = memberMap.get(normalizeSpeaker(speakerMatch[1]));
|
||
if (!member) {
|
||
currentEntry = null;
|
||
continue;
|
||
}
|
||
|
||
currentEntry = {
|
||
id: `${member.id}_${entries.length}_${Date.now()}`,
|
||
speaker: member.name,
|
||
text: speakerMatch[2] || ""
|
||
};
|
||
entries.push(currentEntry);
|
||
continue;
|
||
}
|
||
|
||
if (!currentEntry) {
|
||
continue;
|
||
}
|
||
|
||
if (shouldBreakCurrentEntry(line)) {
|
||
currentEntry = null;
|
||
continue;
|
||
}
|
||
|
||
if (!isContinuationLine(line)) {
|
||
continue;
|
||
}
|
||
|
||
currentEntry.text = currentEntry.text ? `${currentEntry.text}\n${line}` : line;
|
||
}
|
||
|
||
return TEAM_MEMBERS.map((member) => ({
|
||
...member,
|
||
messages: dedupeMessages(entries.filter((entry) => entry.speaker === member.name))
|
||
}));
|
||
}
|
||
|
||
export { TEAM_MEMBERS };
|