Share icon packs between desktop and Android
The Android app's Material icons become a TeamSpeak-format pack shipped in core, which the desktop offers next to the TeamSpeak packs. Android now draws its icons from packs too and imports TeamSpeak's own zips, falling back to the Material pack for what they lack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@@ -0,0 +1,37 @@
|
||||
package com.ts3client.gfx;
|
||||
|
||||
import com.ts3client.net.ClientStatus;
|
||||
|
||||
/**
|
||||
* The TeamSpeak icon keys the channel tree is drawn with, so every frontend asks
|
||||
* the packs for the same icons.
|
||||
*/
|
||||
public final class IconKeys {
|
||||
|
||||
private IconKeys() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the keys to try for a channel, most specific first — packs need not ship
|
||||
* every variant (none of TeamSpeak's own has a subscribed password channel)
|
||||
*/
|
||||
public static String[] channel(boolean password, boolean full, boolean subscribed) {
|
||||
String base = password ? "CHANNEL_PRIVATE" : full ? "CHANNEL_RED" : "CHANNEL_GREEN";
|
||||
return subscribed ? new String[]{base + "_SUBSCRIBED", base} : new String[]{base};
|
||||
}
|
||||
|
||||
public static String client(ClientStatus status) {
|
||||
return switch (status) {
|
||||
case QUERY -> "SERVER_QUERY";
|
||||
case SPEAKERS_DISABLED -> "HARDWARE_OUTPUT_MUTED";
|
||||
case SPEAKERS_MUTED -> "OUTPUT_MUTED";
|
||||
case MIC_DISABLED -> "HARDWARE_INPUT_MUTED";
|
||||
case MIC_MUTED -> "INPUT_MUTED";
|
||||
case AWAY -> "AWAY";
|
||||
case COMMANDER_TALKING -> "PLAYER_COMMANDER_ON";
|
||||
case COMMANDER -> "PLAYER_COMMANDER_OFF";
|
||||
case TALKING -> "PLAYER_ON";
|
||||
case IDLE -> "PLAYER_OFF";
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,8 @@ import java.util.zip.ZipFile;
|
||||
* resolved by convention, picking the size closest to the one that is asked for.
|
||||
*
|
||||
* <p>Icon data is returned as bytes; rasterising it (the packs from 2014 on are
|
||||
* vector art) is the frontend's job.
|
||||
* vector art) is the frontend's job. Vector art may paint with {@code currentColor},
|
||||
* which the frontend sets to its text colour ({@link #withCurrentColor}).
|
||||
*/
|
||||
public final class IconPack {
|
||||
|
||||
@@ -51,20 +52,26 @@ public final class IconPack {
|
||||
private record Entry(String path, int size) {
|
||||
}
|
||||
|
||||
/** Where a pack's files are read from: a zip, a directory or the classpath. */
|
||||
private interface Storage {
|
||||
/** @return the file's bytes, or {@code null} when there is no such file */
|
||||
byte[] read(String path) throws IOException;
|
||||
}
|
||||
|
||||
private final String id;
|
||||
private final File source;
|
||||
private final String name;
|
||||
private final boolean zipped;
|
||||
private final Storage storage;
|
||||
private final boolean fallback;
|
||||
/** Icon key to the images that can serve it, smallest first. */
|
||||
private final Map<String, List<Entry>> entries;
|
||||
|
||||
private IconPack(String id, File source, String name, boolean zipped, boolean fallback,
|
||||
private IconPack(String id, File source, String name, Storage storage, boolean fallback,
|
||||
Map<String, List<Entry>> entries) {
|
||||
this.id = id;
|
||||
this.source = source;
|
||||
this.name = name;
|
||||
this.zipped = zipped;
|
||||
this.storage = storage;
|
||||
this.fallback = fallback;
|
||||
this.entries = entries;
|
||||
}
|
||||
@@ -78,6 +85,7 @@ public final class IconPack {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** @return the pack's zip or directory, or {@code null} for one shipped with the client */
|
||||
public File source() {
|
||||
return source;
|
||||
}
|
||||
@@ -108,7 +116,7 @@ public final class IconPack {
|
||||
Entry entry = select(entries.get(normalizeKey(key)), preferredSize);
|
||||
if (entry == null) return null;
|
||||
try {
|
||||
return zipped ? readFromZip(entry.path()) : Files.readAllBytes(new File(source, entry.path()).toPath());
|
||||
return storage.read(entry.path());
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
@@ -134,14 +142,16 @@ public final class IconPack {
|
||||
return candidates.get(candidates.size() - 1);
|
||||
}
|
||||
|
||||
private byte[] readFromZip(String path) throws IOException {
|
||||
try (ZipFile zip = new ZipFile(source)) {
|
||||
ZipEntry entry = zip.getEntry(path);
|
||||
if (entry == null) return null;
|
||||
try (InputStream in = zip.getInputStream(entry)) {
|
||||
return in.readAllBytes();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets the colour vector art paints with {@code currentColor}, as a stylesheet's
|
||||
* {@code color} would.
|
||||
*
|
||||
* @param rgb the colour as {@code 0xRRGGBB}
|
||||
*/
|
||||
public static byte[] withCurrentColor(byte[] svg, int rgb) {
|
||||
String text = new String(svg, StandardCharsets.UTF_8);
|
||||
if (!text.contains("currentColor")) return svg;
|
||||
return text.replace("currentColor", String.format("#%06X", rgb & 0xFFFFFF)).getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private static String normalizeKey(String key) {
|
||||
@@ -162,6 +172,7 @@ public final class IconPack {
|
||||
|
||||
Map<String, Long> files = zipped ? listZip(source) : listDirectory(source);
|
||||
if (files == null || files.isEmpty()) return null;
|
||||
Storage storage = zipped ? path -> readFromZip(source, path) : path -> readFromDirectory(source, path);
|
||||
|
||||
String iniPath = files.keySet().stream()
|
||||
.filter(p -> p.equalsIgnoreCase(INI))
|
||||
@@ -170,7 +181,7 @@ public final class IconPack {
|
||||
Map<String, String> info = new LinkedHashMap<>();
|
||||
boolean fallback = true;
|
||||
if (iniPath != null) {
|
||||
byte[] ini = read(source, zipped, iniPath);
|
||||
byte[] ini = read(storage, iniPath);
|
||||
if (ini != null) fallback = parseIni(ini, mapping, info);
|
||||
}
|
||||
|
||||
@@ -181,7 +192,35 @@ public final class IconPack {
|
||||
|
||||
String id = source.getName();
|
||||
String name = info.getOrDefault("name", displayName(id));
|
||||
return new IconPack(id, source, name, zipped, fallback, entries);
|
||||
return new IconPack(id, source, name, storage, fallback, entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a pack shipped on the classpath. As a classpath folder cannot be listed,
|
||||
* the pack needs a {@code settings.ini}, whose file names must match exactly.
|
||||
*
|
||||
* @param id the pack's identifier in the settings
|
||||
* @param resource the folder holding it, e.g. {@code /gfx/material}
|
||||
* @return the pack, or {@code null} when it is not there
|
||||
*/
|
||||
public static IconPack loadResource(String id, String resource) {
|
||||
Storage storage = path -> {
|
||||
try (InputStream in = IconPack.class.getResourceAsStream(resource + '/' + path)) {
|
||||
return in == null ? null : in.readAllBytes();
|
||||
}
|
||||
};
|
||||
byte[] ini = read(storage, INI);
|
||||
if (ini == null) return null;
|
||||
Map<String, String> mapping = new LinkedHashMap<>();
|
||||
Map<String, String> info = new LinkedHashMap<>();
|
||||
boolean fallback = parseIni(ini, mapping, info);
|
||||
|
||||
Map<String, List<Entry>> entries = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, String> e : mapping.entrySet()) {
|
||||
entries.put(e.getKey(), List.of(new Entry(e.getValue(), 0)));
|
||||
}
|
||||
if (entries.isEmpty()) return null;
|
||||
return new IconPack(id, null, info.getOrDefault("name", displayName(id)), storage, fallback, entries);
|
||||
}
|
||||
|
||||
/** Turns {@code default_colored_2014.zip} into {@code Default Colored 2014}. */
|
||||
@@ -278,21 +317,29 @@ public final class IconPack {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static byte[] read(File source, boolean zipped, String path) {
|
||||
private static byte[] read(Storage storage, String path) {
|
||||
try {
|
||||
if (!zipped) return Files.readAllBytes(new File(source, path).toPath());
|
||||
try (ZipFile zip = new ZipFile(source)) {
|
||||
ZipEntry entry = zip.getEntry(path);
|
||||
if (entry == null) return null;
|
||||
try (InputStream in = zip.getInputStream(entry)) {
|
||||
return in.readAllBytes();
|
||||
}
|
||||
}
|
||||
return storage.read(path);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] readFromZip(File zipFile, String path) throws IOException {
|
||||
try (ZipFile zip = new ZipFile(zipFile)) {
|
||||
ZipEntry entry = zip.getEntry(path);
|
||||
if (entry == null) return null;
|
||||
try (InputStream in = zip.getInputStream(entry)) {
|
||||
return in.readAllBytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] readFromDirectory(File dir, String path) throws IOException {
|
||||
File file = new File(dir, path);
|
||||
return file.isFile() ? Files.readAllBytes(file.toPath()) : null;
|
||||
}
|
||||
|
||||
private static Map<String, Long> listZip(File file) {
|
||||
if (!file.getName().toLowerCase(Locale.ROOT).endsWith(".zip")) return null;
|
||||
Map<String, Long> files = new LinkedHashMap<>();
|
||||
|
||||
@@ -14,12 +14,16 @@ import java.util.Map;
|
||||
* Finds the icon packs installed on this machine: the client's own {@code gfx/}
|
||||
* folder, an extra folder the user configured, and the {@code gfx/} folder of an
|
||||
* installed TeamSpeak 3 client (whose packs are usable as they are, see
|
||||
* {@link IconPack}).
|
||||
* {@link IconPack}) — plus the Material pack the client ships.
|
||||
*/
|
||||
public final class IconPacks {
|
||||
|
||||
/** The pack every other one falls back to, as TeamSpeak does. */
|
||||
public static final String DEFAULT_ID = "default.zip";
|
||||
/** The pack shipped with the client, drawn from Google's Material icons. */
|
||||
public static final String MATERIAL_ID = "material";
|
||||
|
||||
private static volatile IconPack material;
|
||||
|
||||
private IconPacks() {
|
||||
}
|
||||
@@ -44,11 +48,19 @@ public final class IconPacks {
|
||||
if (pack != null) byId.put(pack.id(), pack);
|
||||
}
|
||||
}
|
||||
IconPack shipped = material();
|
||||
if (shipped != null) byId.putIfAbsent(shipped.id(), shipped);
|
||||
List<IconPack> packs = new ArrayList<>(byId.values());
|
||||
packs.sort(Comparator.comparing(p -> p.name().toLowerCase(Locale.ROOT)));
|
||||
return packs;
|
||||
}
|
||||
|
||||
/** @return the Material pack, or {@code null} if the build left it out */
|
||||
public static IconPack material() {
|
||||
if (material == null) material = IconPack.loadResource(MATERIAL_ID, "/gfx/material");
|
||||
return material;
|
||||
}
|
||||
|
||||
/** @return the pack with this id, or {@code null} when it is not installed */
|
||||
public static IconPack select(List<IconPack> packs, String id) {
|
||||
for (IconPack p : packs) {
|
||||
@@ -57,8 +69,19 @@ public final class IconPacks {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return the pack unresolved icons are taken from, or {@code null} */
|
||||
public static IconPack fallback(List<IconPack> packs) {
|
||||
return select(packs, DEFAULT_ID);
|
||||
/**
|
||||
* The packs to look an icon up in, in turn: the active one, TeamSpeak's
|
||||
* {@code default.zip} if the active pack asks for it, then {@code lastResort}.
|
||||
*
|
||||
* @param active the chosen pack, or {@code null} for none
|
||||
* @param lastResort the pack for whatever is still missing, or {@code null}
|
||||
*/
|
||||
public static List<IconPack> lookupOrder(IconPack active, List<IconPack> packs, IconPack lastResort) {
|
||||
List<IconPack> order = new ArrayList<>(3);
|
||||
if (active != null) order.add(active);
|
||||
IconPack fallback = select(packs, DEFAULT_ID);
|
||||
if (active != null && active.fallsBack() && fallback != null && !order.contains(fallback)) order.add(fallback);
|
||||
if (lastResort != null && !order.contains(lastResort)) order.add(lastResort);
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
1
ts3-client/core/src/main/resources/gfx/material/add.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||
|
After Width: | Height: | Size: 157 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M3 4V1h2v3h3v2H5v3H3V6H0V4h3zm3 6V7h3V4h7l1.83 2H21c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2V10h3zm7 9c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-3.2-5c0 1.77 1.43 3.2 3.2 3.2s3.2-1.43 3.2-3.2-1.43-3.2-3.2-3.2-3.2 1.43-3.2 3.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 370 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M22 4c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4zm-2 13.17L18.83 16H4V4h16v13.17zM13 5h-2v4H7v2h4v4h2v-4h4V9h-4z"/></svg>
|
||||
|
After Width: | Height: | Size: 250 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 7h-5V4c0-1.1-.9-2-2-2h-2c-1.1 0-2 .9-2 2v3H4c-1.1 0-2 .9-2 2v11c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zM9 12c.83 0 1.5.67 1.5 1.5S9.83 15 9 15s-1.5-.67-1.5-1.5S8.17 12 9 12zm3 6H6v-.75c0-1 2-1.5 3-1.5s3 .5 3 1.5V18zm1-9h-2V4h2v5zm5 7.5h-4V15h4v1.5zm0-3h-4V12h4v1.5z"/></svg>
|
||||
|
After Width: | Height: | Size: 401 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#9E8A2E" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12.34 2.02C6.59 1.82 2 6.42 2 12c0 5.52 4.48 10 10 10 3.71 0 6.93-2.02 8.66-5.02-7.51-.25-12.09-8.43-8.32-14.96z"/></svg>
|
||||
|
After Width: | Height: | Size: 230 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#D9443A" fill-opacity="0.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9A7.902 7.902 0 0 1 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1A7.902 7.902 0 0 1 20 12c0 4.42-3.58 8-8 8z"/></svg>
|
||||
|
After Width: | Height: | Size: 366 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#D9443A" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9A7.902 7.902 0 0 1 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1A7.902 7.902 0 0 1 20 12c0 4.42-3.58 8-8 8z"/></svg>
|
||||
|
After Width: | Height: | Size: 347 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"/></svg>
|
||||
|
After Width: | Height: | Size: 181 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M21 7h-2v2h-2V7h-2V5h2V3h2v2h2v2zm-2 14-7-3-7 3V5c0-1.1.9-2 2-2h7a5.002 5.002 0 0 0 5 7.9V21z"/></svg>
|
||||
|
After Width: | Height: | Size: 215 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M21 7h-6V5h6v2zm-2 3.9A5.002 5.002 0 0 1 14 3H7c-1.1 0-2 .9-2 2v16l7-3 7 3V10.9z"/></svg>
|
||||
|
After Width: | Height: | Size: 202 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#2E9BF0" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18 11v2h4v-2h-4zm-2 6.61c.96.71 2.21 1.65 3.2 2.39.4-.53.8-1.07 1.2-1.6-.99-.74-2.24-1.68-3.2-2.4-.4.54-.8 1.08-1.2 1.61zM20.4 5.6c-.4-.53-.8-1.07-1.2-1.6-.99.74-2.24 1.68-3.2 2.4.4.53.8 1.07 1.2 1.6.96-.72 2.21-1.65 3.2-2.4zM4 9c-1.1 0-2 .9-2 2v2c0 1.1.9 2 2 2h1v4h2v-4h1l5 3V6L8 9H4zm11.5 3c0-1.33-.58-2.53-1.5-3.35v6.69c.92-.81 1.5-2.01 1.5-3.34z"/></svg>
|
||||
|
After Width: | Height: | Size: 467 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18 11v2h4v-2h-4zm-2 6.61c.96.71 2.21 1.65 3.2 2.39.4-.53.8-1.07 1.2-1.6-.99-.74-2.24-1.68-3.2-2.4-.4.54-.8 1.08-1.2 1.61zM20.4 5.6c-.4-.53-.8-1.07-1.2-1.6-.99.74-2.24 1.68-3.2 2.4.4.53.8 1.07 1.2 1.6.96-.72 2.21-1.65 3.2-2.4zM4 9c-1.1 0-2 .9-2 2v2c0 1.1.9 2 2 2h1v4h2v-4h1l5 3V6L8 9H4zm5.03 1.71L11 9.53v4.94l-1.97-1.18-.48-.29H4v-2h4.55l.48-.29zM15.5 12c0-1.33-.58-2.53-1.5-3.35v6.69c.92-.81 1.5-2.01 1.5-3.34z"/></svg>
|
||||
|
After Width: | Height: | Size: 534 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-opacity="0.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M4 4h16v12H5.17L4 17.17V4m0-2c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2H4zm2 10h8v2H6v-2zm0-3h12v2H6V9zm0-3h12v2H6V6z"/></svg>
|
||||
|
After Width: | Height: | Size: 281 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M4 4h16v12H5.17L4 17.17V4m0-2c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2H4zm2 10h8v2H6v-2zm0-3h12v2H6V9zm0-3h12v2H6V6z"/></svg>
|
||||
|
After Width: | Height: | Size: 262 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#2E9BF0" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2z"/></svg>
|
||||
|
After Width: | Height: | Size: 183 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#888888" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></svg>
|
||||
|
After Width: | Height: | Size: 241 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
||||
|
After Width: | Height: | Size: 223 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 0H4v2h16V0zM4 24h16v-2H4v2zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 2.75c1.24 0 2.25 1.01 2.25 2.25s-1.01 2.25-2.25 2.25S9.75 10.24 9.75 9 10.76 6.75 12 6.75zM17 17H7v-1.5c0-1.67 3.33-2.5 5-2.5s5 .83 5 2.5V17z"/></svg>
|
||||
|
After Width: | Height: | Size: 374 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>
|
||||
|
After Width: | Height: | Size: 249 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-1 8h-3v3h-2v-3h-3v-2h3V9h2v3h3v2z"/></svg>
|
||||
|
After Width: | Height: | Size: 256 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
|
||||
|
After Width: | Height: | Size: 199 B |
1
ts3-client/core/src/main/resources/gfx/material/dns.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 13H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1v-6c0-.55-.45-1-1-1zM7 19c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM20 3H4c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h16c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM7 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></svg>
|
||||
|
After Width: | Height: | Size: 379 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 20h14v-2H5v2zM19 9h-4V3H9v6H5l7 7 7-7z"/></svg>
|
||||
|
After Width: | Height: | Size: 163 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18.41 5.8 17.2 4.59c-.78-.78-2.05-.78-2.83 0l-2.68 2.68L3 15.96V20h4.04l8.74-8.74 2.63-2.63c.79-.78.79-2.05 0-2.83zM6.21 18H5v-1.21l8.66-8.66 1.21 1.21L6.21 18zM11 20l4-4h6v4H11z"/></svg>
|
||||
|
After Width: | Height: | Size: 301 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10zM8 13.01l1.41 1.41L11 12.84V17h2v-4.16l1.59 1.59L16 13.01 12.01 9 8 13.01z"/></svg>
|
||||
|
After Width: | Height: | Size: 303 B |
1
ts3-client/core/src/main/resources/gfx/material/edit.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a.996.996 0 0 0 0-1.41l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>
|
||||
|
After Width: | Height: | Size: 267 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>
|
||||
|
After Width: | Height: | Size: 218 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg>
|
||||
|
After Width: | Height: | Size: 213 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="m5.25 8.069 2.83-2.827 14.134 14.15-2.83 2.827zm4.236-4.242L12.314.998l5.657 5.656-2.828 2.83zM.999 12.315l2.828-2.829 5.657 5.657-2.828 2.828zM1 21h12v2H1z"/></svg>
|
||||
|
After Width: | Height: | Size: 278 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/><circle cx="8" cy="14" r="2"/><circle cx="12" cy="8" r="2"/><circle cx="16" cy="14" r="2"/></svg>
|
||||
|
After Width: | Height: | Size: 337 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 12.75c1.63 0 3.07.39 4.24.9 1.08.48 1.76 1.56 1.76 2.73V18H6v-1.61c0-1.18.68-2.26 1.76-2.73 1.17-.52 2.61-.91 4.24-.91zM4 13c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm1.13 1.1c-.37-.06-.74-.1-1.13-.1-.99 0-1.93.21-2.78.58A2.01 2.01 0 0 0 0 16.43V18h4.5v-1.61c0-.83.23-1.61.63-2.29zM20 13c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm4 3.43c0-.81-.48-1.53-1.22-1.85A6.95 6.95 0 0 0 20 14c-.39 0-.76.04-1.13.1.4.68.63 1.46.63 2.29V18H24v-1.57zM12 6c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3z"/></svg>
|
||||
|
After Width: | Height: | Size: 626 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#888888" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 4c3.87 0 7 3.13 7 7v2h-2.92L21 17.92V11a9 9 0 0 0-9-9c-1.95 0-3.76.62-5.23 1.68l1.44 1.44A6.914 6.914 0 0 1 12 4zM2.27 1.72 1 3l3.33 3.32A8.899 8.899 0 0 0 3 11v7c0 1.66 1.34 3 3 3h3v-8H5v-2c0-1.17.29-2.26.79-3.22L15 17v4h3c.3 0 .59-.06.86-.14L21 23l1.27-1.27-20-20.01z"/></svg>
|
||||
|
After Width: | Height: | Size: 390 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M4 11h16v2H4z"/></svg>
|
||||
|
After Width: | Height: | Size: 155 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>
|
||||
|
After Width: | Height: | Size: 270 B |
1
ts3-client/core/src/main/resources/gfx/material/info.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg>
|
||||
|
After Width: | Height: | Size: 218 B |
1
ts3-client/core/src/main/resources/gfx/material/list.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"/></svg>
|
||||
|
After Width: | Height: | Size: 208 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-opacity="0.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></svg>
|
||||
|
After Width: | Height: | Size: 366 B |
1
ts3-client/core/src/main/resources/gfx/material/lock.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></svg>
|
||||
|
After Width: | Height: | Size: 347 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M11 7 9.6 8.4l2.6 2.6H2v2h10.2l-2.6 2.6L11 17l5-5-5-5zm9 12h-8v2h8c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-8v2h8v14z"/></svg>
|
||||
|
After Width: | Height: | Size: 231 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="m17 7-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z"/></svg>
|
||||
|
After Width: | Height: | Size: 231 B |
1
ts3-client/core/src/main/resources/gfx/material/mic.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/></svg>
|
||||
|
After Width: | Height: | Size: 313 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#888888" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3S9 3.34 9 5v.18l5.98 5.99zM4.27 3 3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z"/></svg>
|
||||
|
After Width: | Height: | Size: 473 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#9E8A2E" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3S9 3.34 9 5v.18l5.98 5.99zM4.27 3 3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z"/></svg>
|
||||
|
After Width: | Height: | Size: 473 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#D9443A" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3S9 3.34 9 5v.18l5.98 5.99zM4.27 3 3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z"/></svg>
|
||||
|
After Width: | Height: | Size: 473 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M3 11c0 2.45 1.76 4.47 4.08 4.91l-1.49-1.49L7 13l4 4.01L7 21l-1.41-1.41 1.58-1.58v-.06A7.007 7.007 0 0 1 1 11c0-3.87 3.13-7 7-7h3v2H8c-2.76 0-5 2.24-5 5zm19 0V4h-9v7h9zm-2-2h-5V6h5v3zm-7 4h9v7h-9z"/></svg>
|
||||
|
After Width: | Height: | Size: 318 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10.94 8.12 7.48 4.66 9 3h6l1.83 2H20c1.1 0 2 .9 2 2v12c0 .05-.01.1-.02.16l-5.1-5.1c.08-.35.12-.7.12-1.06 0-2.76-2.24-5-5-5-.36 0-.71.04-1.06.12zm9.55 15.19L18.17 21H4c-1.1 0-2-.9-2-2V7c0-.59.27-1.12.68-1.49l-2-2L2.1 2.1l19.8 19.8-1.41 1.41zm-6-5.99-1.5-1.5c-.32.1-.64.18-.99.18-1.66 0-3-1.34-3-3 0-.35.08-.67.19-.98l-1.5-1.5A4.74 4.74 0 0 0 7 13c0 2.76 2.24 5 5 5 .91 0 1.76-.25 2.49-.68z"/></svg>
|
||||
|
After Width: | Height: | Size: 511 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7.58 4.08 6.15 2.65C3.75 4.48 2.17 7.3 2.03 10.5h2a8.445 8.445 0 0 1 3.55-6.42zm12.39 6.42h2c-.15-3.2-1.73-6.02-4.12-7.85l-1.42 1.43a8.495 8.495 0 0 1 3.54 6.42zM18 11c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2v-5zm-6 11c.14 0 .27-.01.4-.04.65-.14 1.18-.58 1.44-1.18.1-.24.15-.5.15-.78h-4c.01 1.1.9 2 2.01 2z"/></svg>
|
||||
|
After Width: | Height: | Size: 500 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-9-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9 4c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
|
After Width: | Height: | Size: 263 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8.65 5.82a3.999 3.999 0 1 1 5.53 5.53L8.65 5.82zM20 17.17c-.02-1.1-.63-2.11-1.61-2.62-.54-.28-1.13-.54-1.77-.76L20 17.17zm1.19 4.02L2.81 2.81 1.39 4.22l8.89 8.89c-1.81.23-3.39.79-4.67 1.45A2.97 2.97 0 0 0 4 17.22V20h13.17l2.61 2.61 1.41-1.42z"/></svg>
|
||||
|
After Width: | Height: | Size: 365 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M14 8c0-2.21-1.79-4-4-4S6 5.79 6 8s1.79 4 4 4 4-1.79 4-4zm-2 0c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zM2 18v2h16v-2c0-2.66-5.33-4-8-4s-8 1.34-8 4zm2 0c.2-.71 3.3-2 6-2 2.69 0 5.77 1.28 6 2H4zm13-8h6v2h-6z"/></svg>
|
||||
|
After Width: | Height: | Size: 330 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M14 8c0-2.21-1.79-4-4-4S6 5.79 6 8s1.79 4 4 4 4-1.79 4-4zm3 2v2h6v-2h-6zM2 18v2h16v-2c0-2.66-5.33-4-8-4s-8 1.34-8 4z"/></svg>
|
||||
|
After Width: | Height: | Size: 238 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13 3h-2v10h2V3zm4.83 2.17-1.42 1.42A6.92 6.92 0 0 1 19 12c0 3.87-3.13 7-7 7A6.995 6.995 0 0 1 7.58 6.58L6.17 5.17A8.932 8.932 0 0 0 3 12a9 9 0 0 0 18 0c0-2.74-1.23-5.18-3.17-6.83z"/></svg>
|
||||
|
After Width: | Height: | Size: 302 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#2E9BF0" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><circle cx="9" cy="9" r="4"/><path d="M9 15c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4zm7.76-9.64-1.68 1.69c.84 1.18.84 2.71 0 3.89l1.68 1.69c2.02-2.02 2.02-5.07 0-7.27zM20.07 2l-1.63 1.63c2.77 3.02 2.77 7.56 0 10.74L20.07 16c3.9-3.89 3.91-9.95 0-14z"/></svg>
|
||||
|
After Width: | Height: | Size: 360 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>
|
||||
|
After Width: | Height: | Size: 324 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z"/></svg>
|
||||
|
After Width: | Height: | Size: 204 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>
|
||||
|
After Width: | Height: | Size: 261 B |
90
ts3-client/core/src/main/resources/gfx/material/settings.ini
Normal file
@@ -0,0 +1,90 @@
|
||||
[info]
|
||||
name = Material
|
||||
|
||||
[options]
|
||||
# Complete for what the client draws; the rest stays with the client's own icons.
|
||||
FALLBACK=false
|
||||
|
||||
[gfxfiles]
|
||||
SERVER_GREEN = dns.svg
|
||||
CHANNEL_GREEN = chat-outlined-a50.svg
|
||||
CHANNEL_GREEN_SUBSCRIBED = chat-outlined.svg
|
||||
CHANNEL_PRIVATE = lock-a50.svg
|
||||
CHANNEL_PRIVATE_SUBSCRIBED = lock.svg
|
||||
CHANNEL_RED = block-d9443a-a50.svg
|
||||
CHANNEL_RED_SUBSCRIBED = block-d9443a.svg
|
||||
CHANNEL_CHAT = chat-outlined.svg
|
||||
CHANNEL_COMMANDER = campaign-outlined.svg
|
||||
PLAYER_OFF = circle-outlined-888888.svg
|
||||
PLAYER_ON = circle-2e9bf0.svg
|
||||
PLAYER_COMMANDER_OFF = campaign-outlined.svg
|
||||
PLAYER_COMMANDER_ON = campaign-2e9bf0.svg
|
||||
AWAY = bedtime-9e8a2e.svg
|
||||
SERVER_QUERY = terminal.svg
|
||||
INPUT_MUTED = mic_off-d9443a.svg
|
||||
INPUT_MUTED_LOCAL = mic_off-9e8a2e.svg
|
||||
OUTPUT_MUTED = volume_off-d9443a.svg
|
||||
HARDWARE_INPUT_MUTED = mic_off-888888.svg
|
||||
HARDWARE_OUTPUT_MUTED = headset_off-888888.svg
|
||||
CAPTURE = mic.svg
|
||||
PLAYBACK = volume_up.svg
|
||||
VOLUME = volume_up.svg
|
||||
ACTIVATE_MICROPHONE = record_voice_over-2e9bf0.svg
|
||||
CONNECT = login.svg
|
||||
DISCONNECT = logout.svg
|
||||
QUIT = power_settings_new.svg
|
||||
SETTINGS = settings.svg
|
||||
REFRESH = refresh.svg
|
||||
FILE_REFRESH = refresh.svg
|
||||
INFO = info.svg
|
||||
ABOUT = info-outlined.svg
|
||||
WARNING = warning.svg
|
||||
ERROR = error.svg
|
||||
CHANNEL_SWITCH = login.svg
|
||||
CHANNEL_CREATE = add.svg
|
||||
CHANNEL_CREATE_SUB = subdirectory_arrow_right.svg
|
||||
CHANNEL_CREATE_SPACER = horizontal_rule.svg
|
||||
CHANNEL_EDIT = edit.svg
|
||||
CHANNEL_DELETE = delete.svg
|
||||
SUBSCRIBE_TO_CHANNEL = visibility.svg
|
||||
UNSUBSCRIBE_FROM_CHANNEL = visibility_off.svg
|
||||
SUBSCRIBE_TO_CHANNEL_FAMILY = visibility-outlined.svg
|
||||
UNSUBSCRIBE_FROM_CHANNEL_FAMILY = visibility_off-outlined.svg
|
||||
SUBSCRIBE_TO_ALL_CHANNELS = visibility.svg
|
||||
UNSUBSCRIBE_FROM_ALL_CHANNELS = visibility_off.svg
|
||||
PLAYER_CHAT = chat-outlined.svg
|
||||
NEW_CHAT = add_comment-outlined.svg
|
||||
POKE = notifications_active.svg
|
||||
CHANGE_NICKNAME = drive_file_rename_outline.svg
|
||||
MOVE_CLIENT_TO_OWN_CHANNEL = move_down.svg
|
||||
KICK_FROM_CHANNEL = remove_circle_outline.svg
|
||||
KICK_FROM_SERVER = remove_circle.svg
|
||||
BAN_CLIENT = gavel.svg
|
||||
BAN_LIST = list.svg
|
||||
PERMISSIONS_SERVER_GROUPS = groups.svg
|
||||
PERMISSIONS_CHANNEL_GROUPS = group_work-outlined.svg
|
||||
ADD_FRIEND = person_add.svg
|
||||
REMOVE_FRIEND = person_remove.svg
|
||||
ADD_FOE = person_off.svg
|
||||
REMOVE_FOE = person_remove-outlined.svg
|
||||
EDIT_FRIEND_FOE_STATUS = contacts.svg
|
||||
CONTACT = contacts.svg
|
||||
IDENTITY_MANAGER = badge.svg
|
||||
BOOKMARK_MANAGER = bookmark.svg
|
||||
BOOKMARK_ADD = bookmark_add.svg
|
||||
BOOKMARK_REMOVE = bookmark_remove.svg
|
||||
UPLOAD_AVATAR = add_a_photo.svg
|
||||
DELETE_AVATAR = no_photography.svg
|
||||
ADD = add.svg
|
||||
EDIT = edit.svg
|
||||
DELETE = delete.svg
|
||||
COPY = content_copy.svg
|
||||
DEFAULT = star.svg
|
||||
CLOSE_BUTTON = close.svg
|
||||
TAB_CLOSE_BUTTON = close.svg
|
||||
FOLDER = folder.svg
|
||||
ADD_FOLDER = create_new_folder.svg
|
||||
FILE_UP = drive_folder_upload.svg
|
||||
FILETRANSFER = swap_vert.svg
|
||||
UPLOAD = upload.svg
|
||||
DOWNLOAD = download.svg
|
||||
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>
|
||||
|
After Width: | Height: | Size: 814 B |
1
ts3-client/core/src/main/resources/gfx/material/star.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>
|
||||
|
After Width: | Height: | Size: 210 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="m19 15-6 6-1.42-1.42L15.17 16H4V4h2v10h9.17l-3.59-3.58L13 9l6 6z"/></svg>
|
||||
|
After Width: | Height: | Size: 186 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3 5 6.99h3V14h2V6.99h3L9 3z"/></svg>
|
||||
|
After Width: | Height: | Size: 192 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16c1.1 0 2-.9 2-2V6a2 2 0 0 0-2-2zm0 14H4V8h16v10zm-2-1h-6v-2h6v2zM7.5 17l-1.41-1.41L8.67 13l-2.59-2.59L7.5 9l4 4-4 4z"/></svg>
|
||||
|
After Width: | Height: | Size: 279 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 20h14v-2H5v2zm0-10h4v6h6v-6h4l-7-7-7 7z"/></svg>
|
||||
|
After Width: | Height: | Size: 164 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 6a9.77 9.77 0 0 1 8.82 5.5C19.17 14.87 15.79 17 12 17s-7.17-2.13-8.82-5.5A9.77 9.77 0 0 1 12 6m0-2C7 4 2.73 7.11 1 11.5 2.73 15.89 7 19 12 19s9.27-3.11 11-7.5C21.27 7.11 17 4 12 4zm0 5a2.5 2.5 0 0 1 0 5 2.5 2.5 0 0 1 0-5m0-2c-2.48 0-4.5 2.02-4.5 4.5S9.52 16 12 16s4.5-2.02 4.5-4.5S14.48 7 12 7z"/></svg>
|
||||
|
After Width: | Height: | Size: 420 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>
|
||||
|
After Width: | Height: | Size: 331 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 6a9.77 9.77 0 0 1 8.82 5.5 9.647 9.647 0 0 1-2.41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53C21.27 7.11 17 4 12 4c-1.27 0-2.49.2-3.64.57l1.65 1.65C10.66 6.09 11.32 6 12 6zm-1.07 1.14L13 9.21c.57.25 1.03.71 1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07C16.5 9.01 14.48 7 12 7c-.37 0-.72.05-1.07.14zM2.01 3.87l2.68 2.68A11.738 11.738 0 0 0 1 11.5C2.73 15.89 7 19 12 19c1.52 0 2.98-.29 4.32-.82l3.42 3.42 1.41-1.41L3.42 2.45 2.01 3.87zm7.5 7.5 2.61 2.61c-.04.01-.08.02-.12.02a2.5 2.5 0 0 1-2.5-2.5c0-.05.01-.08.01-.13zm-3.4-3.4 1.75 1.75a4.6 4.6 0 0 0-.36 1.78 4.507 4.507 0 0 0 6.27 4.14l.98.98c-.88.24-1.8.38-2.75.38a9.77 9.77 0 0 1-8.82-5.5c.7-1.43 1.72-2.61 2.93-3.53z"/></svg>
|
||||
|
After Width: | Height: | Size: 793 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/></svg>
|
||||
|
After Width: | Height: | Size: 627 B |
@@ -0,0 +1 @@
|
||||
<svg fill="#D9443A" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.5 12A4.5 4.5 0 0 0 14 7.97v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51A8.796 8.796 0 0 0 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3 3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06a8.99 8.99 0 0 0 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4 9.91 6.09 12 8.18V4z"/></svg>
|
||||
|
After Width: | Height: | Size: 460 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
|
||||
|
After Width: | Height: | Size: 305 B |
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></svg>
|
||||
|
After Width: | Height: | Size: 172 B |
@@ -1,5 +1,6 @@
|
||||
package com.ts3client.gfx;
|
||||
|
||||
import com.ts3client.net.ClientStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
@@ -124,4 +125,36 @@ class IconPackTest {
|
||||
assertNull(IconPack.load(Files.createDirectory(dir.resolve("empty")).toFile()));
|
||||
assertNull(IconPack.load(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shipsAMaterialPackForEveryIconTheTreeDraws() {
|
||||
IconPack pack = IconPacks.material();
|
||||
assertNotNull(pack);
|
||||
assertEquals("Material", pack.name());
|
||||
assertFalse(pack.fallsBack());
|
||||
assertNull(pack.source());
|
||||
for (ClientStatus status : ClientStatus.values()) {
|
||||
String key = IconKeys.client(status);
|
||||
assertTrue(pack.isVector(key, 16), key);
|
||||
assertNotNull(pack.icon(key, 16), key);
|
||||
}
|
||||
for (boolean password : new boolean[]{false, true}) {
|
||||
for (boolean full : new boolean[]{false, true}) {
|
||||
for (boolean subscribed : new boolean[]{false, true}) {
|
||||
for (String key : IconKeys.channel(password, full, subscribed)) {
|
||||
assertNotNull(pack.icon(key, 16), key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void setsTheColourVectorArtPaintsWith() {
|
||||
byte[] svg = "<svg fill=\"currentColor\"><path fill=\"#123456\"/></svg>".getBytes(StandardCharsets.UTF_8);
|
||||
assertEquals("<svg fill=\"#0A0B0C\"><path fill=\"#123456\"/></svg>",
|
||||
new String(IconPack.withCurrentColor(svg, 0xFF0A0B0C), StandardCharsets.UTF_8));
|
||||
byte[] fixed = "<svg/>".getBytes(StandardCharsets.UTF_8);
|
||||
assertTrue(fixed == IconPack.withCurrentColor(fixed, 0));
|
||||
}
|
||||
}
|
||||
|
||||