cinera: Tweak filter

Introduce nullTopic, visually represent the media in annotations and
default to "exclusive" mode
This commit is contained in:
Matt Mascarenhas 2018-01-15 00:03:11 +00:00
parent 78861a1c78
commit 5e7029d2b0
3 changed files with 247 additions and 105 deletions

View File

@ -14,7 +14,7 @@ typedef struct
version CINERA_APP_VERSION = { version CINERA_APP_VERSION = {
.Major = 0, .Major = 0,
.Minor = 5, .Minor = 5,
.Patch = 24 .Patch = 25
}; };
// TODO(matt): Copy in the DB 3 stuff from cinera_working.c // TODO(matt): Copy in the DB 3 stuff from cinera_working.c
@ -1360,19 +1360,19 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
} }
} }
int CategoryIndex;
if(IsMedium) if(IsMedium)
{ {
for(CategoryIndex = 0; CategoryIndex < LocalMedia->Count; ++CategoryIndex) int MediumIndex;
for(MediumIndex = 0; MediumIndex < LocalMedia->Count; ++MediumIndex)
{ {
if(!StringsDiffer(CategoryMedium[CategoryMediumIndex].Medium, LocalMedia->Category[CategoryIndex].Marker)) if(!StringsDiffer(CategoryMedium[CategoryMediumIndex].Medium, LocalMedia->Category[MediumIndex].Marker))
{ {
return; return;
} }
if((StringsDiffer(CategoryMedium[CategoryMediumIndex].WrittenName, LocalMedia->Category[CategoryIndex].WrittenText)) < 0) if((StringsDiffer(CategoryMedium[CategoryMediumIndex].WrittenName, LocalMedia->Category[MediumIndex].WrittenText)) < 0)
{ {
int CategoryCount; int CategoryCount;
for(CategoryCount = LocalMedia->Count; CategoryCount > CategoryIndex; --CategoryCount) for(CategoryCount = LocalMedia->Count; CategoryCount > MediumIndex; --CategoryCount)
{ {
CopyString(LocalMedia->Category[CategoryCount].Marker, LocalMedia->Category[CategoryCount-1].Marker); CopyString(LocalMedia->Category[CategoryCount].Marker, LocalMedia->Category[CategoryCount-1].Marker);
CopyString(LocalMedia->Category[CategoryCount].WrittenText, LocalMedia->Category[CategoryCount-1].WrittenText); CopyString(LocalMedia->Category[CategoryCount].WrittenText, LocalMedia->Category[CategoryCount-1].WrittenText);
@ -1384,24 +1384,24 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
} }
} }
if(CategoryIndex == LocalMedia->Count) if(MediumIndex == LocalMedia->Count)
{ {
CopyString(LocalMedia->Category[CategoryIndex].Marker, CategoryMedium[CategoryMediumIndex].Medium); CopyString(LocalMedia->Category[MediumIndex].Marker, CategoryMedium[CategoryMediumIndex].Medium);
CopyString(LocalMedia->Category[CategoryIndex].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName); CopyString(LocalMedia->Category[MediumIndex].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName);
} }
++LocalMedia->Count; ++LocalMedia->Count;
for(CategoryIndex = 0; CategoryIndex < GlobalMedia->Count; ++CategoryIndex) for(MediumIndex = 0; MediumIndex < GlobalMedia->Count; ++MediumIndex)
{ {
if(!StringsDiffer(CategoryMedium[CategoryMediumIndex].Medium, GlobalMedia->Category[CategoryIndex].Marker)) if(!StringsDiffer(CategoryMedium[CategoryMediumIndex].Medium, GlobalMedia->Category[MediumIndex].Marker))
{ {
return; return;
} }
if((StringsDiffer(CategoryMedium[CategoryMediumIndex].WrittenName, GlobalMedia->Category[CategoryIndex].WrittenText)) < 0) if((StringsDiffer(CategoryMedium[CategoryMediumIndex].WrittenName, GlobalMedia->Category[MediumIndex].WrittenText)) < 0)
{ {
int CategoryCount; int CategoryCount;
for(CategoryCount = GlobalMedia->Count; CategoryCount > CategoryIndex; --CategoryCount) for(CategoryCount = GlobalMedia->Count; CategoryCount > MediumIndex; --CategoryCount)
{ {
CopyString(GlobalMedia->Category[CategoryCount].Marker, GlobalMedia->Category[CategoryCount-1].Marker); CopyString(GlobalMedia->Category[CategoryCount].Marker, GlobalMedia->Category[CategoryCount-1].Marker);
CopyString(GlobalMedia->Category[CategoryCount].WrittenText, GlobalMedia->Category[CategoryCount-1].WrittenText); CopyString(GlobalMedia->Category[CategoryCount].WrittenText, GlobalMedia->Category[CategoryCount-1].WrittenText);
@ -1413,26 +1413,27 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
} }
} }
if(CategoryIndex == GlobalMedia->Count) if(MediumIndex == GlobalMedia->Count)
{ {
CopyString(GlobalMedia->Category[CategoryIndex].Marker, CategoryMedium[CategoryMediumIndex].Medium); CopyString(GlobalMedia->Category[MediumIndex].Marker, CategoryMedium[CategoryMediumIndex].Medium);
CopyString(GlobalMedia->Category[CategoryIndex].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName); CopyString(GlobalMedia->Category[MediumIndex].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName);
} }
++GlobalMedia->Count; ++GlobalMedia->Count;
} }
else else
{ {
for(CategoryIndex = 0; CategoryIndex < LocalTopics->Count; ++CategoryIndex) int TopicIndex;
for(TopicIndex = 0; TopicIndex < LocalTopics->Count; ++TopicIndex)
{ {
if(!StringsDiffer(Marker, LocalTopics->Category[CategoryIndex].Marker)) if(!StringsDiffer(Marker, LocalTopics->Category[TopicIndex].Marker))
{ {
return; return;
} }
if((StringsDiffer(Marker, LocalTopics->Category[CategoryIndex].Marker)) < 0) if((StringsDiffer(Marker, LocalTopics->Category[TopicIndex].Marker)) < 0)
{ {
int CategoryCount; int CategoryCount;
for(CategoryCount = LocalTopics->Count; CategoryCount > CategoryIndex; --CategoryCount) for(CategoryCount = LocalTopics->Count; CategoryCount > TopicIndex; --CategoryCount)
{ {
CopyString(LocalTopics->Category[CategoryCount].Marker, LocalTopics->Category[CategoryCount-1].Marker); CopyString(LocalTopics->Category[CategoryCount].Marker, LocalTopics->Category[CategoryCount-1].Marker);
} }
@ -1442,35 +1443,40 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
} }
} }
if(CategoryIndex == LocalTopics->Count) if(TopicIndex == LocalTopics->Count)
{ {
CopyString(LocalTopics->Category[CategoryIndex].Marker, Marker); CopyString(LocalTopics->Category[TopicIndex].Marker, Marker);
} }
++LocalTopics->Count; ++LocalTopics->Count;
for(CategoryIndex = 0; CategoryIndex < GlobalTopics->Count; ++CategoryIndex) for(TopicIndex = 0; TopicIndex < GlobalTopics->Count; ++TopicIndex)
{ {
if(!StringsDiffer(Marker, GlobalTopics->Category[CategoryIndex].Marker)) if(!StringsDiffer(Marker, GlobalTopics->Category[TopicIndex].Marker))
{ {
return; return;
} }
if((StringsDiffer(Marker, GlobalTopics->Category[CategoryIndex].Marker)) < 0) // NOTE(matt): This successfully sorts "nullTopic" at the end, but maybe figure out a more general way to force the
// order of stuff, perhaps blocks of dudes that should sort to the start / end
if(((StringsDiffer(Marker, GlobalTopics->Category[TopicIndex].Marker)) < 0 || !StringsDiffer(GlobalTopics->Category[TopicIndex].Marker, "nullTopic")))
{ {
int CategoryCount; if(StringsDiffer(Marker, "nullTopic")) // NOTE(matt): This test (with the above || condition) forces nullTopic never to be inserted, only appended
for(CategoryCount = GlobalTopics->Count; CategoryCount > CategoryIndex; --CategoryCount)
{ {
CopyString(GlobalTopics->Category[CategoryCount].Marker, GlobalTopics->Category[CategoryCount-1].Marker); int CategoryCount;
} for(CategoryCount = GlobalTopics->Count; CategoryCount > TopicIndex; --CategoryCount)
{
CopyString(GlobalTopics->Category[CategoryCount].Marker, GlobalTopics->Category[CategoryCount-1].Marker);
}
CopyString(GlobalTopics->Category[CategoryCount].Marker, Marker); CopyString(GlobalTopics->Category[CategoryCount].Marker, Marker);
break; break;
}
} }
} }
if(CategoryIndex == GlobalTopics->Count) if(TopicIndex == GlobalTopics->Count)
{ {
CopyString(GlobalTopics->Category[CategoryIndex].Marker, Marker); CopyString(GlobalTopics->Category[TopicIndex].Marker, Marker);
} }
++GlobalTopics->Count; ++GlobalTopics->Count;
@ -1478,35 +1484,81 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
} }
void void
BuildCategories(buffer *AnnotationClass, buffer *TopicDots, categories *LocalTopics, categories *LocalMedia, int *MarkerIndex) BuildCategories(buffer *AnnotationClass, buffer *CategoryIcons, categories *LocalTopics, categories *LocalMedia, int *MarkerIndex, char *DefaultMedium)
{ {
if(LocalTopics->Count > 0) bool CategoriesSpan = FALSE;
if(!(LocalTopics->Count == 1 && !StringsDiffer(LocalTopics->Category[0].Marker, "nullTopic")
&& LocalMedia->Count == 1 && !StringsDiffer(LocalMedia->Category[0].Marker, DefaultMedium)))
{ {
CopyStringToBuffer(TopicDots, "<span class=\"categories\">"); CategoriesSpan = TRUE;
for(int i = 0; i < LocalTopics->Count; ++i) CopyStringToBuffer(CategoryIcons, "<span class=\"cineraCategories\">");
{
CopyStringToBuffer(TopicDots, "<div title=\"%s\" class=\"category %s\"></div>",
SanitisePunctuation(LocalTopics->Category[i].Marker),
SanitisePunctuation(LocalTopics->Category[i].Marker));
CopyStringToBuffer(AnnotationClass, " cat_%s",
SanitisePunctuation(LocalTopics->Category[i].Marker));
}
CopyStringToBuffer(TopicDots, "</span>");
} }
for(int i = 0; i < LocalMedia->Count; ++i) if(LocalTopics->Count == 1 && !StringsDiffer(LocalTopics->Category[0].Marker, "nullTopic"))
{ {
if(!StringsDiffer(LocalMedia->Category[i].Marker, "afk")) // TODO(matt): Initially hidden config char SanitisedMarker[StringLength(LocalTopics->Category[0].Marker)];
CopyString(SanitisedMarker, LocalTopics->Category[0].Marker);
SanitisePunctuation(SanitisedMarker);
CopyStringToBuffer(AnnotationClass, " cat_%s", SanitisedMarker);
}
else
{
for(int i = 0; i < LocalTopics->Count; ++i)
{ {
CopyStringToBuffer(AnnotationClass, " off_%s skip", SanitisePunctuation(LocalMedia->Category[i].Marker)); // TODO(matt): Bulletproof this? char SanitisedMarker[StringLength(LocalTopics->Category[i].Marker)];
CopyString(SanitisedMarker, LocalTopics->Category[i].Marker);
SanitisePunctuation(SanitisedMarker);
CopyStringToBuffer(CategoryIcons, "<div title=\"%s\" class=\"category %s\"></div>",
LocalTopics->Category[i].Marker,
SanitisedMarker);
CopyStringToBuffer(AnnotationClass, " cat_%s",
SanitisedMarker);
} }
else }
if(LocalMedia->Count == 1 && !StringsDiffer(LocalMedia->Category[0].Marker, DefaultMedium))
{
char SanitisedMarker[StringLength(LocalMedia->Category[0].Marker)];
CopyString(SanitisedMarker, LocalMedia->Category[0].Marker);
SanitisePunctuation(SanitisedMarker);
CopyStringToBuffer(AnnotationClass, " %s", SanitisedMarker);
}
else
{
for(int i = 0; i < LocalMedia->Count; ++i)
{ {
CopyStringToBuffer(AnnotationClass, " %s", SanitisePunctuation(LocalMedia->Category[i].Marker)); char SanitisedMarker[StringLength(LocalMedia->Category[i].Marker)];
CopyString(SanitisedMarker, LocalMedia->Category[i].Marker);
SanitisePunctuation(SanitisedMarker);
if(!StringsDiffer(LocalMedia->Category[i].Marker, "afk")) // TODO(matt): Initially hidden config
{
CopyStringToBuffer(AnnotationClass, " off_%s skip", SanitisedMarker); // TODO(matt): Bulletproof this?
}
else
{
for(int j = 0; j < ArrayCount(CategoryMedium); ++j)
{
if(!StringsDiffer(LocalMedia->Category[i].Marker, CategoryMedium[j].Medium))
{
CopyStringToBuffer(CategoryIcons, "<div title=\"%s\" class=\"categoryMedium %s\">%s</div>",
LocalMedia->Category[i].WrittenText,
LocalMedia->Category[i].Marker,
CategoryMedium[j].Icon);
CopyStringToBuffer(AnnotationClass, " %s", SanitisedMarker);
}
}
}
} }
} }
if(CategoriesSpan)
{
CopyStringToBuffer(CategoryIcons, "</span>");
}
CopyStringToBuffer(AnnotationClass, "\""); CopyStringToBuffer(AnnotationClass, "\"");
} }
@ -1702,6 +1754,10 @@ BuildQuote(quote_info *Info, char *Speaker, int ID)
int int
GenerateTopicColours(char *Topic) GenerateTopicColours(char *Topic)
{ {
char SanitisedTopic[StringLength(Topic)];
CopyString(SanitisedTopic, Topic);
SanitisePunctuation(SanitisedTopic);
for(int i = 0; i < ArrayCount(CategoryMedium); ++i) for(int i = 0; i < ArrayCount(CategoryMedium); ++i)
{ {
if(!StringsDiffer(Topic, CategoryMedium[i].Medium)) if(!StringsDiffer(Topic, CategoryMedium[i].Medium))
@ -1766,7 +1822,7 @@ GenerateTopicColours(char *Topic)
while(Topics.Buffer.Ptr - Topics.Buffer.Location < Topics.Buffer.Size) while(Topics.Buffer.Ptr - Topics.Buffer.Location < Topics.Buffer.Size)
{ {
Topics.Buffer.Ptr += StringLength(".category."); Topics.Buffer.Ptr += StringLength(".category.");
if(!StringsDifferT(SanitisePunctuation(Topic), Topics.Buffer.Ptr, ' ')) if(!StringsDifferT(SanitisedTopic, Topics.Buffer.Ptr, ' '))
{ {
FreeBuffer(&Topics.Buffer); FreeBuffer(&Topics.Buffer);
fclose(Topics.Handle); fclose(Topics.Handle);
@ -1779,10 +1835,18 @@ GenerateTopicColours(char *Topic)
++Topics.Buffer.Ptr; ++Topics.Buffer.Ptr;
} }
hsl_colour Colour; if(!StringsDiffer(Topic, "nullTopic"))
StringToColourHash(&Colour, Topic); {
fprintf(Topics.Handle, ".category.%s { border: 1px solid hsl(%d, %d%%, %d%%); background: hsl(%d, %d%%, %d%%); }\n", fprintf(Topics.Handle, ".category.%s { border: 1px solid transparent; background: transparent; }\n",
SanitisePunctuation(Topic), Colour.Hue, Colour.Saturation, Colour.Lightness, Colour.Hue, Colour.Saturation, Colour.Lightness); SanitisedTopic);
}
else
{
hsl_colour Colour;
StringToColourHash(&Colour, Topic);
fprintf(Topics.Handle, ".category.%s { border: 1px solid hsl(%d, %d%%, %d%%); background: hsl(%d, %d%%, %d%%); }\n",
SanitisedTopic, Colour.Hue, Colour.Saturation, Colour.Lightness, Colour.Hue, Colour.Saturation, Colour.Lightness);
}
fclose(Topics.Handle); fclose(Topics.Handle);
FreeBuffer(&Topics.Buffer); FreeBuffer(&Topics.Buffer);
@ -2367,7 +2431,7 @@ HMMLToBuffers(buffers *CollationBuffers, template **BespokeTemplate, char *Filen
buffer AnnotationClass; buffer AnnotationClass;
buffer AnnotationData; buffer AnnotationData;
buffer Text; buffer Text;
buffer TopicDots; buffer CategoryIcons;
buffer FilterState; buffer FilterState;
@ -2464,14 +2528,14 @@ HMMLToBuffers(buffers *CollationBuffers, template **BespokeTemplate, char *Filen
// AnnotationClass // AnnotationClass
// AnnotationData // AnnotationData
// Text // Text
// TopicDots // CategoryIcons
if(ClaimBuffer(&Annotation, "Annotation", Kilobytes(8)) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; }; if(ClaimBuffer(&Annotation, "Annotation", Kilobytes(8)) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; };
if(ClaimBuffer(&AnnotationHeader, "AnnotationHeader", 512) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; }; if(ClaimBuffer(&AnnotationHeader, "AnnotationHeader", 512) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; };
if(ClaimBuffer(&AnnotationClass, "AnnotationClass", 256) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; }; if(ClaimBuffer(&AnnotationClass, "AnnotationClass", 256) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; };
if(ClaimBuffer(&AnnotationData, "AnnotationData", 512) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; }; if(ClaimBuffer(&AnnotationData, "AnnotationData", 512) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; };
if(ClaimBuffer(&Text, "Text", Kilobytes(4)) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; }; if(ClaimBuffer(&Text, "Text", Kilobytes(4)) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; };
if(ClaimBuffer(&TopicDots, "TopicDots", 512) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; }; if(ClaimBuffer(&CategoryIcons, "CategoryIcons", 512) == RC_ARENA_FULL) { hmml_free(&HMML); return RC_ARENA_FULL; };
CopyStringToBuffer(&AnnotationHeader, CopyStringToBuffer(&AnnotationHeader,
" <div data-timestamp=\"%d\"", " <div data-timestamp=\"%d\"",
@ -2855,7 +2919,7 @@ AppendedIdentifier:
case RC_ERROR_MEMORY: case RC_ERROR_MEMORY:
hmml_free(&HMML); hmml_free(&HMML);
return RC_ERROR_FATAL; return RC_ERROR_FATAL;
}; }
if(!HasFilterMenu) if(!HasFilterMenu)
{ {
HasFilterMenu = TRUE; HasFilterMenu = TRUE;
@ -2864,12 +2928,27 @@ AppendedIdentifier:
++MarkerIndex; ++MarkerIndex;
} }
if(LocalTopics.Count == 0)
{
switch(GenerateTopicColours("nullTopic"))
{
case RC_SUCCESS:
case RC_NOOP:
break;
case RC_ERROR_FILE:
case RC_ERROR_MEMORY:
hmml_free(&HMML);
return RC_ERROR_FATAL;
};
InsertCategory(&Topics, &LocalTopics, &Media, &LocalMedia, "nullTopic");
}
if(LocalMedia.Count == 0) if(LocalMedia.Count == 0)
{ {
InsertCategory(&Topics, &LocalTopics, &Media, &LocalMedia, DefaultMedium); InsertCategory(&Topics, &LocalTopics, &Media, &LocalMedia, DefaultMedium);
} }
BuildCategories(&AnnotationClass, &TopicDots, &LocalTopics, &LocalMedia, &MarkerIndex); BuildCategories(&AnnotationClass, &CategoryIcons, &LocalTopics, &LocalMedia, &MarkerIndex, DefaultMedium);
CopyBuffer(&AnnotationHeader, &AnnotationClass); CopyBuffer(&AnnotationHeader, &AnnotationClass);
if(HasQuote || HasReference) if(HasQuote || HasReference)
@ -2888,7 +2967,7 @@ AppendedIdentifier:
if(LocalTopics.Count > 0) if(LocalTopics.Count > 0)
{ {
CopyBuffer(&Annotation, &TopicDots); CopyBuffer(&Annotation, &CategoryIcons);
} }
CopyStringToBuffer(&Annotation, "</div>\n" CopyStringToBuffer(&Annotation, "</div>\n"
@ -2900,7 +2979,7 @@ AppendedIdentifier:
if(LocalTopics.Count > 0) if(LocalTopics.Count > 0)
{ {
CopyBuffer(&Annotation, &TopicDots); CopyBuffer(&Annotation, &CategoryIcons);
} }
CopyStringToBuffer(&Annotation, "</div>\n" CopyStringToBuffer(&Annotation, "</div>\n"
@ -2913,7 +2992,7 @@ AppendedIdentifier:
if(LocalTopics.Count > 0) if(LocalTopics.Count > 0)
{ {
CopyBuffer(&Annotation, &TopicDots); CopyBuffer(&Annotation, &CategoryIcons);
} }
CopyStringToBuffer(&Annotation, "</div>\n" CopyStringToBuffer(&Annotation, "</div>\n"
@ -2923,14 +3002,14 @@ AppendedIdentifier:
CopyBuffer(&CollationBuffers->Player, &Annotation); CopyBuffer(&CollationBuffers->Player, &Annotation);
// NOTE(matt): Tree structure of "annotation local" buffer dependencies // NOTE(matt): Tree structure of "annotation local" buffer dependencies
// TopicDots // CategoryIcons
// Text // Text
// AnnotationData // AnnotationData
// AnnotationClass // AnnotationClass
// AnnotationHeader // AnnotationHeader
// Annotation // Annotation
DeclaimBuffer(&TopicDots); DeclaimBuffer(&CategoryIcons);
DeclaimBuffer(&Text); DeclaimBuffer(&Text);
DeclaimBuffer(&AnnotationData); DeclaimBuffer(&AnnotationData);
DeclaimBuffer(&AnnotationClass); DeclaimBuffer(&AnnotationClass);
@ -3012,24 +3091,33 @@ AppendedIdentifier:
if(HasFilterMenu) if(HasFilterMenu)
{ {
// NOTE(matt): Two loops, one for each JS "object"
CopyStringToBuffer(&FilterState, "\n<script>\n" CopyStringToBuffer(&FilterState, "\n<script>\n"
" var filterInitState = {\n"); " var filterInitState = {\n");
for(int i = 0; i < Topics.Count; ++i) for(int i = 0; i < Topics.Count; ++i)
{ {
char SanitisedMarker[StringLength(Topics.Category[i].Marker)];
CopyString(SanitisedMarker, Topics.Category[i].Marker);
SanitisePunctuation(SanitisedMarker);
CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
Topics.Category[i].Marker, "topic"); SanitisedMarker, "topic");
} }
for(int i = 0; i < Media.Count; ++i) for(int i = 0; i < Media.Count; ++i)
{ {
char SanitisedMarker[StringLength(Media.Category[i].Marker)];
CopyString(SanitisedMarker, Media.Category[i].Marker);
SanitisePunctuation(SanitisedMarker);
if(!StringsDiffer(Media.Category[i].Marker, "afk")) // TODO(matt): Make this configurable? if(!StringsDiffer(Media.Category[i].Marker, "afk")) // TODO(matt): Make this configurable?
{ {
CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": true },\n", CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": true },\n",
Media.Category[i].Marker, "medium"); SanitisedMarker, "medium");
} }
else else
{ {
CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
Media.Category[i].Marker, "medium"); SanitisedMarker, "medium");
} }
} }
CopyStringToBuffer(&FilterState, CopyStringToBuffer(&FilterState,
@ -3038,20 +3126,28 @@ AppendedIdentifier:
" var filterState = {\n"); " var filterState = {\n");
for(int i = 0; i < Topics.Count; ++i) for(int i = 0; i < Topics.Count; ++i)
{ {
char SanitisedMarker[StringLength(Topics.Category[i].Marker)];
CopyString(SanitisedMarker, Topics.Category[i].Marker);
SanitisePunctuation(SanitisedMarker);
CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
Topics.Category[i].Marker, "topic"); SanitisedMarker, "topic");
} }
for(int i = 0; i < Media.Count; ++i) for(int i = 0; i < Media.Count; ++i)
{ {
char SanitisedMarker[StringLength(Media.Category[i].Marker)];
CopyString(SanitisedMarker, Media.Category[i].Marker);
SanitisePunctuation(SanitisedMarker);
if(!StringsDiffer(Media.Category[i].Marker, "afk")) // TODO(matt): Make this configurable? if(!StringsDiffer(Media.Category[i].Marker, "afk")) // TODO(matt): Make this configurable?
{ {
CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": true },\n", CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": true },\n",
Media.Category[i].Marker, "medium"); SanitisedMarker, "medium");
} }
else else
{ {
CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n", CopyStringToBuffer(&FilterState, "\"%s\":\t{ \"type\": \"%s\",\t\"off\": false },\n",
Media.Category[i].Marker, "medium"); SanitisedMarker, "medium");
} }
} }
@ -3066,7 +3162,7 @@ AppendedIdentifier:
" <div class=\"menu filter\">\n" " <div class=\"menu filter\">\n"
" <span><img src=\"%scinera_icon_filter.png\"></span>\n" " <span><img src=\"%scinera_icon_filter.png\"></span>\n"
" <div class=\"filter_container\">\n" " <div class=\"filter_container\">\n"
" <div class=\"filter_mode inclusive\">Filter mode: </div>\n" " <div class=\"filter_mode exclusive\">Filter mode: </div>\n"
" <div class=\"filters\">\n", " <div class=\"filters\">\n",
URLPrefix.Location); URLPrefix.Location);
DeclaimBuffer(&URLPrefix); DeclaimBuffer(&URLPrefix);
@ -3078,13 +3174,20 @@ AppendedIdentifier:
" <div class=\"filter_title\">Topics</div>\n"); " <div class=\"filter_title\">Topics</div>\n");
for(int i = 0; i < Topics.Count; ++i) for(int i = 0; i < Topics.Count; ++i)
{ {
char SanitisedMarker[StringLength(Topics.Category[i].Marker)];
CopyString(SanitisedMarker, Topics.Category[i].Marker);
SanitisePunctuation(SanitisedMarker);
bool NullTopic = !StringsDiffer(Topics.Category[i].Marker, "nullTopic");
CopyStringToBuffer(&FilterTopics, CopyStringToBuffer(&FilterTopics,
" <div class=\"filter_content %s\">\n" " <div %sclass=\"filter_content %s\">\n"
" <span class=\"icon category %s\"></span><span class=\"cineraText\">%s</span>\n" " <span class=\"icon category %s\"></span><span class=\"cineraText\">%s</span>\n"
" </div>\n", " </div>\n",
Topics.Category[i].Marker,
Topics.Category[i].Marker, NullTopic ? "title=\"Annotations that don't fit into the above topic(s) may be filtered using this pseudo-topic\" " : "",
Topics.Category[i].Marker); SanitisedMarker,
SanitisedMarker,
NullTopic ? "(null topic)" : Topics.Category[i].Marker);
} }
CopyStringToBuffer(&FilterTopics, CopyStringToBuffer(&FilterTopics,
" </div>\n"); " </div>\n");
@ -3098,6 +3201,10 @@ AppendedIdentifier:
" <div class=\"filter_title\">Media</div>\n"); " <div class=\"filter_title\">Media</div>\n");
for(int i = 0; i < Media.Count; ++i) for(int i = 0; i < Media.Count; ++i)
{ {
char SanitisedMarker[StringLength(Media.Category[i].Marker)];
CopyString(SanitisedMarker, Media.Category[i].Marker);
SanitisePunctuation(SanitisedMarker);
int j; int j;
for(j = 0; j < ArrayCount(CategoryMedium); ++j) for(j = 0; j < ArrayCount(CategoryMedium); ++j)
{ {
@ -3108,26 +3215,28 @@ AppendedIdentifier:
} }
if(!StringsDiffer(Media.Category[i].Marker, "afk")) // TODO(matt): Initially hidden config if(!StringsDiffer(Media.Category[i].Marker, "afk")) // TODO(matt): Initially hidden config
// When we do this for real, we'll probably need to loop
// over the configured media to see who should be hidden
{ {
CopyStringToBuffer(&FilterMedia, CopyStringToBuffer(&FilterMedia,
" <div class=\"filter_content %s off\">\n" " <div class=\"filter_content %s off\">\n"
" <span class=\"icon\">%s</span><span class=\"cineraText\">%s</span>\n" " <span class=\"icon\">%s</span><span class=\"cineraText\">%s</span>\n"
" </div>\n", " </div>\n",
Media.Category[i].Marker, SanitisedMarker,
CategoryMedium[j].Icon, CategoryMedium[j].Icon,
CategoryMedium[j].WrittenName CategoryMedium[j].WrittenName);
);
} }
else else
{ {
CopyStringToBuffer(&FilterMedia, CopyStringToBuffer(&FilterMedia,
" <div class=\"filter_content %s\">\n" " <div class=\"filter_content %s\">\n"
" <span class=\"icon\">%s</span><span class=\"cineraText\">%s</span>\n" " <span class=\"icon\">%s</span><span class=\"cineraText\">%s%s</span>\n"
" </div>\n", " </div>\n",
Media.Category[i].Marker, SanitisedMarker,
CategoryMedium[j].Icon, CategoryMedium[j].Icon,
CategoryMedium[j].WrittenName CategoryMedium[j].WrittenName,
); !StringsDiffer(Media.Category[i].Marker, DefaultMedium) ? "</span><span class=\"cineraDefaultMediumIndicator\" title=\"Default medium\n"
"Annotations lacking a media icon are in this medium\">&#128969;" : "");
} }
} }
CopyStringToBuffer(&FilterMedia, CopyStringToBuffer(&FilterMedia,
@ -3463,7 +3572,10 @@ AppendedIdentifier:
{ {
for(int i = 0; i < Topics.Count; ++i) for(int i = 0; i < Topics.Count; ++i)
{ {
CopyStringToBuffer(&CollationBuffers->IncludesPlayer, "%s, ", Topics.Category[i].Marker); if(StringsDiffer(Topics.Category[i].Marker, "nullTopic"))
{
CopyStringToBuffer(&CollationBuffers->IncludesPlayer, "%s, ", Topics.Category[i].Marker);
}
} }
} }

View File

@ -239,11 +239,14 @@
z-index: 1; z-index: 1;
} }
.cineraMenus > .menu .refs, .cineraMenus > .menu .refs {
.cineraMenus > .menu .filter_container {
width: 350px; width: 350px;
} }
.cineraMenus > .menu .filter_container {
min-width: 350px;
}
.cineraMenus > .menu .credits_container { .cineraMenus > .menu .credits_container {
min-width: 240px; min-width: 240px;
} }
@ -370,25 +373,41 @@
.cineraMenus > .menu > .filter_container .filters > * { .cineraMenus > .menu > .filter_container .filters > * {
width: 50%; width: 50%;
flex-grow: 1;
} }
.cineraMenus > .menu > .filter_container .filter_content { .cineraDefaultMediumIndicator {
color: #FEF697;
}
.cineraMenus > .menu > .filter_container .filter_content,
.cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories {
cursor: pointer; cursor: pointer;
display: flex;
align-items: center;
} }
.cineraMenus > .menu > .filter_container .filter_content .icon { .cineraMenus > .menu > .filter_container .filter_content .icon,
margin: 0 4px; .cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories .categoryMedium {
font-style: normal;
margin-left: 4px;
}
.cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories .categoryMedium + .categoryMedium {
margin-left: 2px;
} }
.cineraMenus > .menu > .filter_container .filter_content.off .icon { .cineraMenus > .menu > .filter_container .filter_content.off .icon {
background: transparent; background: transparent;
} }
.cineraMenus > .menu > .filter_container .filter_content.rant .icon { .cineraMenus > .menu > .filter_container .filter_content.rant .icon,
color: #F00; .cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories .categoryMedium.rant {
color: #BA0001;
} }
.cineraMenus > .menu > .filter_container .filter_media .filter_content.off .icon { .cineraMenus > .menu > .filter_container .filter_media .filter_content.off .icon,
.cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories .categoryMedium.off {
opacity: 0.32; opacity: 0.32;
} }
@ -447,12 +466,7 @@
.cineraMenus .filter_content.authored .cineraText, .cineraMenus .filter_content.authored .cineraText,
.cineraPlayerContainer .markers_container > .marker.authored, .cineraPlayerContainer .markers_container > .marker.authored,
.cineraPlayerContainer .markers_container > .marker.off_authored { .cineraPlayerContainer .markers_container > .marker.off_authored {
font-style: oblique; font-style: oblique !important;
}
.cineraPlayerContainer .markers_container > .marker.off_authored,
.cineraPlayerContainer .markers_container > .marker.off_rant {
opacity: 0.5;
} }
.cineraPlayerContainer .markers_container > .marker .cineraContent sup { .cineraPlayerContainer .markers_container > .marker .cineraContent sup {
@ -477,7 +491,7 @@
top: -2px; top: -2px;
} }
.cineraPlayerContainer .markers_container > .marker .cineraContent .categories { .cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories {
display: inline-flex; display: inline-flex;
margin: 4px; margin: 4px;
} }
@ -487,18 +501,18 @@
} }
.cineraMenus > .menu > .filter_container .filter_content .category, .cineraMenus > .menu > .filter_container .filter_content .category,
.cineraPlayerContainer .markers_container > .marker .cineraContent .categories .category { .cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories .category {
border-radius: 50%; border-radius: 50%;
height: 5px; height: 5px;
width: 5px; width: 5px;
} }
.cineraMenus > .menu > .filter_container .filter_content .category.off, .cineraMenus > .menu > .filter_container .filter_content .category.off,
.cineraPlayerContainer .markers_container > .marker .cineraContent .categories .category.off { .cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories .category.off {
background: transparent; background: transparent;
} }
.cineraPlayerContainer .markers_container > .marker .cineraContent .categories .category { .cineraPlayerContainer .markers_container > .marker .cineraContent .cineraCategories .category {
margin-left: 2px; margin-left: 2px;
} }

View File

@ -875,7 +875,7 @@ function filterItemToggle(filterItem) {
{ {
filterItem.querySelector(".icon").style.backgroundColor = "transparent"; filterItem.querySelector(".icon").style.backgroundColor = "transparent";
} }
var testMarkers = document.querySelectorAll(".marker." + selectedCategory + ", .marker.cat_" + selectedCategory); var testMarkers = playerContainer.querySelectorAll(".marker." + selectedCategory + ", .marker.cat_" + selectedCategory);
for(var j = 0; j < testMarkers.length; ++j) for(var j = 0; j < testMarkers.length; ++j)
{ {
if(filterState[selectedCategory].type == "topic") if(filterState[selectedCategory].type == "topic")
@ -894,6 +894,14 @@ function filterItemToggle(filterItem) {
} }
else else
{ {
var markerCategories = testMarkers[j].querySelectorAll(".categoryMedium." + selectedCategory);
for(var k = 0; k < markerCategories.length; ++k)
{
if(markerCategories[k].classList.contains(selectedCategory))
{
markerCategories[k].classList.add("off");
}
}
testMarkers[j].classList.remove(selectedCategory); testMarkers[j].classList.remove(selectedCategory);
testMarkers[j].classList.add("off_" + selectedCategory); testMarkers[j].classList.add("off_" + selectedCategory);
} }
@ -951,6 +959,14 @@ function filterItemToggle(filterItem) {
{ {
testMarkers[j].classList.remove("off_" + selectedCategory); testMarkers[j].classList.remove("off_" + selectedCategory);
testMarkers[j].classList.add(selectedCategory); testMarkers[j].classList.add(selectedCategory);
var markerCategories = testMarkers[j].querySelectorAll(".categoryMedium." + selectedCategory);
for(var k = 0; k < markerCategories.length; ++k)
{
if(markerCategories[k].classList.contains(selectedCategory))
{
markerCategories[k].classList.remove("off");
}
}
} }
Skipping = 0; Skipping = 0;
@ -990,7 +1006,7 @@ function resetFilter() {
} }
} }
if(filterMode == "exclusive") if(filterMode == "inclusive")
{ {
toggleFilterMode(); toggleFilterMode();
} }