Merge 26406e204e
into 2b49a4dfe7
4
app/assets/images/social_link_icons/bluesky.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" viewBox="0 0 512 512">
|
||||
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
|
||||
<path d="M111.8 62.2C170.2 105.9 233 194.7 256 242.4c23-47.6 85.8-136.4 144.2-180.2c42.1-31.6 110.3-56 110.3 21.8c0 15.5-8.9 130.5-14.1 149.2C478.2 298 412 314.6 353.1 304.5c102.9 17.5 129.1 75.5 72.5 133.5c-107.4 110.2-154.3-27.6-166.3-62.9l0 0c-1.7-4.9-2.6-7.8-3.3-7.8s-1.6 3-3.3 7.8l0 0c-12 35.3-59 173.1-166.3 62.9c-56.5-58-30.4-116 72.5-133.5C100 314.6 33.8 298 15.7 233.1C10.4 214.4 1.5 99.4 1.5 83.9c0-77.8 68.2-53.4 110.3-21.8z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 702 B |
3
app/assets/images/social_link_icons/discord.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-discord" viewBox="0 0 16 16">
|
||||
<path d="M13.545 2.907a13.2 13.2 0 0 0-3.257-1.011.05.05 0 0 0-.052.025c-.141.25-.297.577-.406.833a12.2 12.2 0 0 0-3.658 0 8 8 0 0 0-.412-.833.05.05 0 0 0-.052-.025c-1.125.194-2.22.534-3.257 1.011a.04.04 0 0 0-.021.018C.356 6.024-.213 9.047.066 12.032q.003.022.021.037a13.3 13.3 0 0 0 3.995 2.02.05.05 0 0 0 .056-.019q.463-.63.818-1.329a.05.05 0 0 0-.01-.059l-.018-.011a9 9 0 0 1-1.248-.595.05.05 0 0 1-.02-.066l.015-.019q.127-.095.248-.195a.05.05 0 0 1 .051-.007c2.619 1.196 5.454 1.196 8.041 0a.05.05 0 0 1 .053.007q.121.1.248.195a.05.05 0 0 1-.004.085 8 8 0 0 1-1.249.594.05.05 0 0 0-.03.03.05.05 0 0 0 .003.041c.24.465.515.909.817 1.329a.05.05 0 0 0 .056.019 13.2 13.2 0 0 0 4.001-2.02.05.05 0 0 0 .021-.037c.334-3.451-.559-6.449-2.366-9.106a.03.03 0 0 0-.02-.019m-8.198 7.307c-.789 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612m5.316 0c-.788 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
3
app/assets/images/social_link_icons/facebook.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-facebook" viewBox="0 0 16 16">
|
||||
<path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951"/>
|
||||
</svg>
|
After Width: | Height: | Size: 430 B |
3
app/assets/images/social_link_icons/github.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-github" viewBox="0 0 16 16">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
|
||||
</svg>
|
After Width: | Height: | Size: 703 B |
3
app/assets/images/social_link_icons/gitlab.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-gitlab" viewBox="0 0 16 16">
|
||||
<path d="m15.734 6.1-.022-.058L13.534.358a.57.57 0 0 0-.563-.356.6.6 0 0 0-.328.122.6.6 0 0 0-.193.294l-1.47 4.499H5.025l-1.47-4.5A.572.572 0 0 0 2.47.358L.289 6.04l-.022.057A4.044 4.044 0 0 0 1.61 10.77l.007.006.02.014 3.318 2.485 1.64 1.242 1 .755a.67.67 0 0 0 .814 0l1-.755 1.64-1.242 3.338-2.5.009-.007a4.05 4.05 0 0 0 1.34-4.668Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 466 B |
3
app/assets/images/social_link_icons/instagram.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-instagram" viewBox="0 0 16 16">
|
||||
<path d="M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.9 3.9 0 0 0-1.417.923A3.9 3.9 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.9 3.9 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.9 3.9 0 0 0-.923-1.417A3.9 3.9 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599s.453.546.598.92c.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.5 2.5 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.5 2.5 0 0 1-.92-.598 2.5 2.5 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233s.008-2.388.046-3.231c.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92s.546-.453.92-.598c.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92m-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217m0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
3
app/assets/images/social_link_icons/line.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-line" viewBox="0 0 16 16">
|
||||
<path d="M8 0c4.411 0 8 2.912 8 6.492 0 1.433-.555 2.723-1.715 3.994-1.678 1.932-5.431 4.285-6.285 4.645-.83.35-.734-.197-.696-.413l.003-.018.114-.685c.027-.204.055-.521-.026-.723-.09-.223-.444-.339-.704-.395C2.846 12.39 0 9.701 0 6.492 0 2.912 3.59 0 8 0M5.022 7.686H3.497V4.918a.156.156 0 0 0-.155-.156H2.78a.156.156 0 0 0-.156.156v3.486c0 .041.017.08.044.107v.001l.002.002.002.002a.15.15 0 0 0 .108.043h2.242c.086 0 .155-.07.155-.156v-.56a.156.156 0 0 0-.155-.157m.791-2.924a.156.156 0 0 0-.156.156v3.486c0 .086.07.155.156.155h.562c.086 0 .155-.07.155-.155V4.918a.156.156 0 0 0-.155-.156zm3.863 0a.156.156 0 0 0-.156.156v2.07L7.923 4.832l-.013-.015v-.001l-.01-.01-.003-.003-.011-.009h-.001L7.88 4.79l-.003-.002-.005-.003-.008-.005h-.002l-.003-.002-.01-.004-.004-.002-.01-.003h-.002l-.003-.001-.009-.002h-.006l-.003-.001h-.004l-.002-.001h-.574a.156.156 0 0 0-.156.155v3.486c0 .086.07.155.156.155h.56c.087 0 .157-.07.157-.155v-2.07l1.6 2.16a.2.2 0 0 0 .039.038l.001.001.01.006.004.002.008.004.007.003.005.002.01.003h.003a.2.2 0 0 0 .04.006h.56c.087 0 .157-.07.157-.155V4.918a.156.156 0 0 0-.156-.156zm3.815.717v-.56a.156.156 0 0 0-.155-.157h-2.242a.16.16 0 0 0-.108.044h-.001l-.001.002-.002.003a.16.16 0 0 0-.044.107v3.486c0 .041.017.08.044.107l.002.003.002.002a.16.16 0 0 0 .108.043h2.242c.086 0 .155-.07.155-.156v-.56a.156.156 0 0 0-.155-.157H11.81v-.589h1.525c.086 0 .155-.07.155-.156v-.56a.156.156 0 0 0-.155-.157H11.81v-.589h1.525c.086 0 .155-.07.155-.156Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
3
app/assets/images/social_link_icons/linkedin.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-linkedin" viewBox="0 0 16 16">
|
||||
<path d="M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854zm4.943 12.248V6.169H2.542v7.225zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248S2.4 3.226 2.4 3.934c0 .694.521 1.248 1.327 1.248zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016l.016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 661 B |
3
app/assets/images/social_link_icons/mastodon.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-mastodon" viewBox="0 0 16 16">
|
||||
<path d="M11.19 12.195c2.016-.24 3.77-1.475 3.99-2.603.348-1.778.32-4.339.32-4.339 0-3.47-2.286-4.488-2.286-4.488C12.062.238 10.083.017 8.027 0h-.05C5.92.017 3.942.238 2.79.765c0 0-2.285 1.017-2.285 4.488l-.002.662c-.004.64-.007 1.35.011 2.091.083 3.394.626 6.74 3.78 7.57 1.454.383 2.703.463 3.709.408 1.823-.1 2.847-.647 2.847-.647l-.06-1.317s-1.303.41-2.767.36c-1.45-.05-2.98-.156-3.215-1.928a4 4 0 0 1-.033-.496s1.424.346 3.228.428c1.103.05 2.137-.064 3.188-.189zm1.613-2.47H11.13v-4.08c0-.859-.364-1.295-1.091-1.295-.804 0-1.207.517-1.207 1.541v2.233H7.168V5.89c0-1.024-.403-1.541-1.207-1.541-.727 0-1.091.436-1.091 1.296v4.079H3.197V5.522q0-1.288.66-2.046c.456-.505 1.052-.764 1.793-.764.856 0 1.504.328 1.933.983L8 4.39l.417-.695c.429-.655 1.077-.983 1.934-.983.74 0 1.336.259 1.791.764q.662.757.661 2.046z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 947 B |
3
app/assets/images/social_link_icons/medium.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-medium" viewBox="0 0 16 16">
|
||||
<path d="M9.025 8c0 2.485-2.02 4.5-4.513 4.5A4.506 4.506 0 0 1 0 8c0-2.486 2.02-4.5 4.512-4.5A4.506 4.506 0 0 1 9.025 8m4.95 0c0 2.34-1.01 4.236-2.256 4.236S9.463 10.339 9.463 8c0-2.34 1.01-4.236 2.256-4.236S13.975 5.661 13.975 8M16 8c0 2.096-.355 3.795-.794 3.795-.438 0-.793-1.7-.793-3.795 0-2.096.355-3.795.794-3.795.438 0 .793 1.699.793 3.795"/>
|
||||
</svg>
|
After Width: | Height: | Size: 478 B |
3
app/assets/images/social_link_icons/other.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-globe" viewBox="0 0 16 16">
|
||||
<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m7.5-6.923c-.67.204-1.335.82-1.887 1.855A8 8 0 0 0 5.145 4H7.5zM4.09 4a9.3 9.3 0 0 1 .64-1.539 7 7 0 0 1 .597-.933A7.03 7.03 0 0 0 2.255 4zm-.582 3.5c.03-.877.138-1.718.312-2.5H1.674a7 7 0 0 0-.656 2.5zM4.847 5a12.5 12.5 0 0 0-.338 2.5H7.5V5zM8.5 5v2.5h2.99a12.5 12.5 0 0 0-.337-2.5zM4.51 8.5a12.5 12.5 0 0 0 .337 2.5H7.5V8.5zm3.99 0V11h2.653c.187-.765.306-1.608.338-2.5zM5.145 12q.208.58.468 1.068c.552 1.035 1.218 1.65 1.887 1.855V12zm.182 2.472a7 7 0 0 1-.597-.933A9.3 9.3 0 0 1 4.09 12H2.255a7 7 0 0 0 3.072 2.472M3.82 11a13.7 13.7 0 0 1-.312-2.5h-2.49c.062.89.291 1.733.656 2.5zm6.853 3.472A7 7 0 0 0 13.745 12H11.91a9.3 9.3 0 0 1-.64 1.539 7 7 0 0 1-.597.933M8.5 12v2.923c.67-.204 1.335-.82 1.887-1.855q.26-.487.468-1.068zm3.68-1h2.146c.365-.767.594-1.61.656-2.5h-2.49a13.7 13.7 0 0 1-.312 2.5m2.802-3.5a7 7 0 0 0-.656-2.5H12.18c.174.782.282 1.623.312 2.5zM11.27 2.461c.247.464.462.98.64 1.539h1.835a7 7 0 0 0-3.072-2.472c.218.284.418.598.597.933M10.855 4a8 8 0 0 0-.468-1.068C9.835 1.897 9.17 1.282 8.5 1.077V4z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
3
app/assets/images/social_link_icons/quora.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-quora" viewBox="0 0 16 16">
|
||||
<path d="M8.73 12.476c-.554-1.091-1.204-2.193-2.473-2.193-.242 0-.484.04-.707.142l-.43-.863c.525-.45 1.373-.808 2.464-.808 1.697 0 2.568.818 3.26 1.86.41-.89.605-2.093.605-3.584 0-3.724-1.165-5.636-3.885-5.636-2.68 0-3.839 1.912-3.839 5.636 0 3.704 1.159 5.596 3.84 5.596.425 0 .811-.046 1.166-.15Zm.665 1.3a7 7 0 0 1-1.83.244C3.994 14.02.5 11.172.5 7.03.5 2.849 3.995 0 7.564 0c3.63 0 7.09 2.828 7.09 7.03 0 2.337-1.09 4.236-2.675 5.464.512.767 1.04 1.277 1.773 1.277.802 0 1.125-.62 1.179-1.105h1.043c.061.647-.262 3.334-3.178 3.334-1.767 0-2.7-1.024-3.4-2.224Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 694 B |
4
app/assets/images/social_link_icons/reddit.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-reddit" viewBox="0 0 16 16">
|
||||
<path d="M6.167 8a.83.83 0 0 0-.83.83c0 .459.372.84.83.831a.831.831 0 0 0 0-1.661m1.843 3.647c.315 0 1.403-.038 1.976-.611a.23.23 0 0 0 0-.306.213.213 0 0 0-.306 0c-.353.363-1.126.487-1.67.487-.545 0-1.308-.124-1.671-.487a.213.213 0 0 0-.306 0 .213.213 0 0 0 0 .306c.564.563 1.652.61 1.977.61zm.992-2.807c0 .458.373.83.831.83s.83-.381.83-.83a.831.831 0 0 0-1.66 0z"/>
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.828-1.165c-.315 0-.602.124-.812.325-.801-.573-1.9-.945-3.121-.993l.534-2.501 1.738.372a.83.83 0 1 0 .83-.869.83.83 0 0 0-.744.468l-1.938-.41a.2.2 0 0 0-.153.028.2.2 0 0 0-.086.134l-.592 2.788c-1.24.038-2.358.41-3.17.992-.21-.2-.496-.324-.81-.324a1.163 1.163 0 0 0-.478 2.224q-.03.17-.029.353c0 1.795 2.091 3.256 4.669 3.256s4.668-1.451 4.668-3.256c0-.114-.01-.238-.029-.353.401-.181.688-.592.688-1.069 0-.65-.525-1.165-1.165-1.165"/>
|
||||
</svg>
|
After Width: | Height: | Size: 979 B |
3
app/assets/images/social_link_icons/skype.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-skype" viewBox="0 0 16 16">
|
||||
<path d="M4.671 0c.88 0 1.733.247 2.468.702a7.42 7.42 0 0 1 6.02 2.118 7.37 7.37 0 0 1 2.167 5.215q0 .517-.072 1.026a4.66 4.66 0 0 1 .6 2.281 4.64 4.64 0 0 1-1.37 3.294A4.67 4.67 0 0 1 11.18 16c-.84 0-1.658-.226-2.37-.644a7.42 7.42 0 0 1-6.114-2.107A7.37 7.37 0 0 1 .529 8.035q0-.545.08-1.081a4.644 4.644 0 0 1 .76-5.59A4.68 4.68 0 0 1 4.67 0zm.447 7.01c.18.309.43.572.729.769a7 7 0 0 0 1.257.653q.737.308 1.145.523c.229.112.437.264.615.448.135.142.21.331.21.528a.87.87 0 0 1-.335.723c-.291.196-.64.289-.99.264a2.6 2.6 0 0 1-1.048-.206 11 11 0 0 1-.532-.253 1.3 1.3 0 0 0-.587-.15.72.72 0 0 0-.501.176.63.63 0 0 0-.195.491.8.8 0 0 0 .148.482 1.2 1.2 0 0 0 .456.354 5.1 5.1 0 0 0 2.212.419 4.6 4.6 0 0 0 1.624-.265 2.3 2.3 0 0 0 1.08-.801c.267-.39.402-.855.386-1.327a2.1 2.1 0 0 0-.279-1.101 2.5 2.5 0 0 0-.772-.792A7 7 0 0 0 8.486 7.3a1 1 0 0 0-.145-.058 18 18 0 0 1-1.013-.447 1.8 1.8 0 0 1-.54-.387.73.73 0 0 1-.2-.508.8.8 0 0 1 .385-.723 1.76 1.76 0 0 1 .968-.247c.26-.003.52.03.772.096q.412.119.802.293c.105.049.22.075.336.076a.6.6 0 0 0 .453-.19.7.7 0 0 0 .18-.496.72.72 0 0 0-.17-.476 1.4 1.4 0 0 0-.556-.354 3.7 3.7 0 0 0-.708-.183 6 6 0 0 0-1.022-.078 4.5 4.5 0 0 0-1.536.258 2.7 2.7 0 0 0-1.174.784 1.9 1.9 0 0 0-.45 1.287c-.01.37.076.736.25 1.063"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
3
app/assets/images/social_link_icons/slack.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-slack" viewBox="0 0 16 16">
|
||||
<path d="M3.362 10.11c0 .926-.756 1.681-1.681 1.681S0 11.036 0 10.111.756 8.43 1.68 8.43h1.682zm.846 0c0-.924.756-1.68 1.681-1.68s1.681.756 1.681 1.68v4.21c0 .924-.756 1.68-1.68 1.68a1.685 1.685 0 0 1-1.682-1.68zM5.89 3.362c-.926 0-1.682-.756-1.682-1.681S4.964 0 5.89 0s1.68.756 1.68 1.68v1.682zm0 .846c.924 0 1.68.756 1.68 1.681S6.814 7.57 5.89 7.57H1.68C.757 7.57 0 6.814 0 5.89c0-.926.756-1.682 1.68-1.682zm6.749 1.682c0-.926.755-1.682 1.68-1.682S16 4.964 16 5.889s-.756 1.681-1.68 1.681h-1.681zm-.848 0c0 .924-.755 1.68-1.68 1.68A1.685 1.685 0 0 1 8.43 5.89V1.68C8.43.757 9.186 0 10.11 0c.926 0 1.681.756 1.681 1.68zm-1.681 6.748c.926 0 1.682.756 1.682 1.681S11.036 16 10.11 16s-1.681-.756-1.681-1.68v-1.682h1.68zm0-.847c-.924 0-1.68-.755-1.68-1.68s.756-1.681 1.68-1.681h4.21c.924 0 1.68.756 1.68 1.68 0 .926-.756 1.681-1.68 1.681z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 966 B |
3
app/assets/images/social_link_icons/snapchat.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-snapchat" viewBox="0 0 16 16">
|
||||
<path d="M15.943 11.526c-.111-.303-.323-.465-.564-.599a1 1 0 0 0-.123-.064l-.219-.111c-.752-.399-1.339-.902-1.746-1.498a3.4 3.4 0 0 1-.3-.531c-.034-.1-.032-.156-.008-.207a.3.3 0 0 1 .097-.1c.129-.086.262-.173.352-.231.162-.104.289-.187.371-.245.309-.216.525-.446.66-.702a1.4 1.4 0 0 0 .069-1.16c-.205-.538-.713-.872-1.329-.872a1.8 1.8 0 0 0-.487.065c.006-.368-.002-.757-.035-1.139-.116-1.344-.587-2.048-1.077-2.61a4.3 4.3 0 0 0-1.095-.881C9.764.216 8.92 0 7.999 0s-1.76.216-2.505.641c-.412.232-.782.53-1.097.883-.49.562-.96 1.267-1.077 2.61-.033.382-.04.772-.036 1.138a1.8 1.8 0 0 0-.487-.065c-.615 0-1.124.335-1.328.873a1.4 1.4 0 0 0 .067 1.161c.136.256.352.486.66.701.082.058.21.14.371.246l.339.221a.4.4 0 0 1 .109.11c.026.053.027.11-.012.217a3.4 3.4 0 0 1-.295.52c-.398.583-.968 1.077-1.696 1.472-.385.204-.786.34-.955.8-.128.348-.044.743.28 1.075q.18.189.409.31a4.4 4.4 0 0 0 1 .4.7.7 0 0 1 .202.09c.118.104.102.26.259.488q.12.178.296.3c.33.229.701.243 1.095.258.355.014.758.03 1.217.18.19.064.389.186.618.328.55.338 1.305.802 2.566.802 1.262 0 2.02-.466 2.576-.806.227-.14.424-.26.609-.321.46-.152.863-.168 1.218-.181.393-.015.764-.03 1.095-.258a1.14 1.14 0 0 0 .336-.368c.114-.192.11-.327.217-.42a.6.6 0 0 1 .19-.087 4.5 4.5 0 0 0 1.014-.404c.16-.087.306-.2.429-.336l.004-.005c.304-.325.38-.709.256-1.047m-1.121.602c-.684.378-1.139.337-1.493.565-.3.193-.122.61-.34.76-.269.186-1.061-.012-2.085.326-.845.279-1.384 1.082-2.903 1.082s-2.045-.801-2.904-1.084c-1.022-.338-1.816-.14-2.084-.325-.218-.15-.041-.568-.341-.761-.354-.228-.809-.187-1.492-.563-.436-.24-.189-.39-.044-.46 2.478-1.199 2.873-3.05 2.89-3.188.022-.166.045-.297-.138-.466-.177-.164-.962-.65-1.18-.802-.36-.252-.52-.503-.402-.812.082-.214.281-.295.49-.295a1 1 0 0 1 .197.022c.396.086.78.285 1.002.338q.04.01.082.011c.118 0 .16-.06.152-.195-.026-.433-.087-1.277-.019-2.066.094-1.084.444-1.622.859-2.097.2-.229 1.137-1.22 2.93-1.22 1.792 0 2.732.987 2.931 1.215.416.475.766 1.013.859 2.098.068.788.009 1.632-.019 2.065-.01.142.034.195.152.195a.4.4 0 0 0 .082-.01c.222-.054.607-.253 1.002-.338a1 1 0 0 1 .197-.023c.21 0 .409.082.49.295.117.309-.04.56-.401.812-.218.152-1.003.638-1.18.802-.184.169-.16.3-.139.466.018.14.413 1.991 2.89 3.189.147.073.394.222-.041.464"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
4
app/assets/images/social_link_icons/stackoverflow.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-stack-overflow" viewBox="0 0 16 16">
|
||||
<path d="M12.412 14.572V10.29h1.428V16H1v-5.71h1.428v4.282z"/>
|
||||
<path d="M3.857 13.145h7.137v-1.428H3.857zM10.254 0 9.108.852l4.26 5.727 1.146-.852zm-3.54 3.377 5.484 4.567.913-1.097L7.627 2.28l-.914 1.097zM4.922 6.55l6.47 3.013.603-1.294-6.47-3.013zm-.925 3.344 6.985 1.469.294-1.398-6.985-1.468z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 438 B |
3
app/assets/images/social_link_icons/strava.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-strava" viewBox="0 0 16 16">
|
||||
<path d="M6.731 0 2 9.125h2.788L6.73 5.497l1.93 3.628h2.766zm4.694 9.125-1.372 2.756L8.66 9.125H6.547L10.053 16l3.484-6.875z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 256 B |
3
app/assets/images/social_link_icons/substack.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-substack" viewBox="0 0 16 16">
|
||||
<path d="M15 3.604H1v1.891h14v-1.89ZM1 7.208V16l7-3.926L15 16V7.208zM15 0H1v1.89h14z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 218 B |
3
app/assets/images/social_link_icons/telegram.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-telegram" viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.287 5.906q-1.168.486-4.666 2.01-.567.225-.595.442c-.03.243.275.339.69.47l.175.055c.408.133.958.288 1.243.294q.39.01.868-.32 3.269-2.206 3.374-2.23c.05-.012.12-.026.166.016s.042.12.037.141c-.03.129-1.227 1.241-1.846 1.817-.193.18-.33.307-.358.336a8 8 0 0 1-.188.186c-.38.366-.664.64.015 1.088.327.216.589.393.85.571.284.194.568.387.936.629q.14.092.27.187c.331.236.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.4 1.4 0 0 0-.013-.315.34.34 0 0 0-.114-.217.53.53 0 0 0-.31-.093c-.3.005-.763.166-2.984 1.09"/>
|
||||
</svg>
|
After Width: | Height: | Size: 706 B |
3
app/assets/images/social_link_icons/threads.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-threads" viewBox="0 0 16 16">
|
||||
<path d="M6.321 6.016c-.27-.18-1.166-.802-1.166-.802.756-1.081 1.753-1.502 3.132-1.502.975 0 1.803.327 2.394.948s.928 1.509 1.005 2.644q.492.207.905.484c1.109.745 1.719 1.86 1.719 3.137 0 2.716-2.226 5.075-6.256 5.075C4.594 16 1 13.987 1 7.994 1 2.034 4.482 0 8.044 0 9.69 0 13.55.243 15 5.036l-1.36.353C12.516 1.974 10.163 1.43 8.006 1.43c-3.565 0-5.582 2.171-5.582 6.79 0 4.143 2.254 6.343 5.63 6.343 2.777 0 4.847-1.443 4.847-3.556 0-1.438-1.208-2.127-1.27-2.127-.236 1.234-.868 3.31-3.644 3.31-1.618 0-3.013-1.118-3.013-2.582 0-2.09 1.984-2.847 3.55-2.847.586 0 1.294.04 1.663.114 0-.637-.54-1.728-1.9-1.728-1.25 0-1.566.405-1.967.868ZM8.716 8.19c-2.04 0-2.304.87-2.304 1.416 0 .878 1.043 1.168 1.6 1.168 1.02 0 2.067-.282 2.232-2.423a6.2 6.2 0 0 0-1.528-.161"/>
|
||||
</svg>
|
After Width: | Height: | Size: 896 B |
3
app/assets/images/social_link_icons/tiktok.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-tiktok" viewBox="0 0 16 16">
|
||||
<path d="M9 0h1.98c.144.715.54 1.617 1.235 2.512C12.895 3.389 13.797 4 15 4v2c-1.753 0-3.07-.814-4-1.829V11a5 5 0 1 1-5-5v2a3 3 0 1 0 3 3z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 270 B |
4
app/assets/images/social_link_icons/twitch.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-twitch" viewBox="0 0 16 16">
|
||||
<path d="M3.857 0 1 2.857v10.286h3.429V16l2.857-2.857H9.57L14.714 8V0zm9.714 7.429-2.285 2.285H9l-2 2v-2H4.429V1.143h9.142z"/>
|
||||
<path d="M11.857 3.143h-1.143V6.57h1.143zm-3.143 0H7.571V6.57h1.143z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 329 B |
3
app/assets/images/social_link_icons/twitter_x.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-twitter-x" viewBox="0 0 16 16">
|
||||
<path d="M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 296 B |
3
app/assets/images/social_link_icons/vimeo.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-vimeo" viewBox="0 0 16 16">
|
||||
<path d="M15.992 4.204q-.106 2.334-3.262 6.393-3.263 4.243-5.522 4.243-1.4 0-2.367-2.583L3.55 7.523Q2.83 4.939 2.007 4.94q-.178.001-1.254.754L0 4.724a210 210 0 0 0 2.334-2.081q1.581-1.364 2.373-1.437 1.865-.185 2.298 2.553.466 2.952.646 3.666.54 2.447 1.186 2.445.5 0 1.508-1.587 1.006-1.587 1.077-2.415.144-1.37-1.077-1.37a3 3 0 0 0-1.185.261q1.183-3.86 4.508-3.756 2.466.075 2.324 3.2z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 518 B |
3
app/assets/images/social_link_icons/whatsapp.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-whatsapp" viewBox="0 0 16 16">
|
||||
<path d="M13.601 2.326A7.85 7.85 0 0 0 7.994 0C3.627 0 .068 3.558.064 7.926c0 1.399.366 2.76 1.057 3.965L0 16l4.204-1.102a7.9 7.9 0 0 0 3.79.965h.004c4.368 0 7.926-3.558 7.93-7.93A7.9 7.9 0 0 0 13.6 2.326zM7.994 14.521a6.6 6.6 0 0 1-3.356-.92l-.24-.144-2.494.654.666-2.433-.156-.251a6.56 6.56 0 0 1-1.007-3.505c0-3.626 2.957-6.584 6.591-6.584a6.56 6.56 0 0 1 4.66 1.931 6.56 6.56 0 0 1 1.928 4.66c-.004 3.639-2.961 6.592-6.592 6.592m3.615-4.934c-.197-.099-1.17-.578-1.353-.646-.182-.065-.315-.099-.445.099-.133.197-.513.646-.627.775-.114.133-.232.148-.43.05-.197-.1-.836-.308-1.592-.985-.59-.525-.985-1.175-1.103-1.372-.114-.198-.011-.304.088-.403.087-.088.197-.232.296-.346.1-.114.133-.198.198-.33.065-.134.034-.248-.015-.347-.05-.099-.445-1.076-.612-1.47-.16-.389-.323-.335-.445-.34-.114-.007-.247-.007-.38-.007a.73.73 0 0 0-.529.247c-.182.198-.691.677-.691 1.654s.71 1.916.81 2.049c.098.133 1.394 2.132 3.383 2.992.47.205.84.326 1.129.418.475.152.904.129 1.246.08.38-.058 1.171-.48 1.338-.943.164-.464.164-.86.114-.943-.049-.084-.182-.133-.38-.232"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
3
app/assets/images/social_link_icons/youtube.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#212529" class="bi bi-youtube" viewBox="0 0 16 16">
|
||||
<path d="M8.051 1.999h.089c.822.003 4.987.033 6.11.335a2.01 2.01 0 0 1 1.415 1.42c.101.38.172.883.22 1.402l.01.104.022.26.008.104c.065.914.073 1.77.074 1.957v.075c-.001.194-.01 1.108-.082 2.06l-.008.105-.009.104c-.05.572-.124 1.14-.235 1.558a2.01 2.01 0 0 1-1.415 1.42c-1.16.312-5.569.334-6.18.335h-.142c-.309 0-1.587-.006-2.927-.052l-.17-.006-.087-.004-.171-.007-.171-.007c-1.11-.049-2.167-.128-2.654-.26a2.01 2.01 0 0 1-1.415-1.419c-.111-.417-.185-.986-.235-1.558L.09 9.82l-.008-.104A31 31 0 0 1 0 7.68v-.123c.002-.215.01-.958.064-1.778l.007-.103.003-.052.008-.104.022-.26.01-.104c.048-.519.119-1.023.22-1.402a2.01 2.01 0 0 1 1.415-1.42c.487-.13 1.544-.21 2.654-.26l.17-.007.172-.006.086-.003.171-.007A100 100 0 0 1 7.858 2zM6.4 5.209v4.818l4.157-2.408z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 888 B |
|
@ -10,6 +10,35 @@ $(function () {
|
|||
const defaultHomeZoom = 12;
|
||||
let map, marker, deleted_lat, deleted_lon;
|
||||
|
||||
if ($("#social_links").length) {
|
||||
$("#add-social-link").click(function (event) {
|
||||
event.preventDefault();
|
||||
const newIndex = -Date.now();
|
||||
const socialLinkForm = $(`
|
||||
<div class="social-link-added-fields row mb-3">
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="user[social_links_attributes][${newIndex}][url]" id="user_social_links_attributes_${newIndex}_url">
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-primary col-sm-2 align-self-start">${I18n.t("profiles.edit.social_links.remove")}</button>
|
||||
</div>
|
||||
`);
|
||||
|
||||
socialLinkForm.find("button").click(function () {
|
||||
$(this).parent().remove();
|
||||
});
|
||||
|
||||
$("#social_links").append(socialLinkForm);
|
||||
});
|
||||
|
||||
$(".social_link_destroy input[type='checkbox']").change(function () {
|
||||
$(this).parent().parent().addClass("d-none");
|
||||
});
|
||||
|
||||
$(".social_link_destroy input[type='checkbox']:checked").each(function () {
|
||||
$(this).parent().parent().addClass("d-none");
|
||||
});
|
||||
}
|
||||
|
||||
if ($("#map").length) {
|
||||
map = L.map("map", {
|
||||
attributionControl: false,
|
||||
|
|
|
@ -12,6 +12,9 @@ class ProfilesController < ApplicationController
|
|||
def edit; end
|
||||
|
||||
def update
|
||||
social_links_params = params.require(:user).permit(:social_links_attributes => [:id, :url, :_destroy])
|
||||
current_user.assign_attributes(social_links_params)
|
||||
|
||||
if params[:user][:description] != current_user.description
|
||||
current_user.description = params[:user][:description]
|
||||
current_user.description_format = "markdown"
|
||||
|
|
68
app/models/social_link.rb
Normal file
|
@ -0,0 +1,68 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: social_links
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# user_id :bigint not null
|
||||
# url :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_social_links_on_user_id (user_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# fk_rails_... (user_id => users.id)
|
||||
#
|
||||
|
||||
class SocialLink < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
validates :url, :format => { :with => %r{\Ahttps?://.+\z}, :message => :http_parse_error }
|
||||
|
||||
URL_PATTERNS = {
|
||||
:bluesky => %r{\Ahttps?://(?:www\.)?bsky\.app/profile/([a-zA-Z0-9\._-]+)},
|
||||
:discord => %r{\Ahttps?://(?:www\.)?discord\.com/users/(\d+)},
|
||||
:facebook => %r{\Ahttps?://(?:www\.)?facebook\.com/([a-zA-Z0-9.]+)},
|
||||
:github => %r{\Ahttps?://(?:www\.)?github\.com/([a-zA-Z0-9_-]+)},
|
||||
:gitlab => %r{\Ahttps?://(?:www\.)?gitlab\.com/([a-zA-Z0-9_-]+)},
|
||||
:instagram => %r{\Ahttps?://(?:www\.)?instagram\.com/([a-zA-Z0-9._]+)},
|
||||
:linkedin => %r{\Ahttps?://(?:www\.)?linkedin\.com/in/([a-zA-Z0-9_-]+)},
|
||||
:line => %r{\Ahttps?://(?:www\.)?line\.me/ti/p/([a-zA-Z0-9_-]+)},
|
||||
:mastodon => %r{\Ahttps?://(?:(?:www\.)?mastodon\.social|en\.osm\.town)/@([a-zA-Z0-9_]+)},
|
||||
:medium => %r{\Ahttps?://(?:www\.)?medium\.com/@([a-zA-Z0-9_]+)},
|
||||
:quora => %r{\Ahttps?://(?:www\.)?quora\.com/profile/([a-zA-Z0-9_-]+)},
|
||||
:reddit => %r{\Ahttps?://(?:www\.)?reddit\.com/user/([a-zA-Z0-9_-]+)},
|
||||
:skype => %r{\Ahttps?://join\.skype\.com/invite/([a-zA-Z0-9_-]+)},
|
||||
:slack => %r{\Ahttps?://join\.slack\.com/shareDM/([a-zA-Z0-9_~-]+)},
|
||||
:snapchat => %r{\Ahttps?://(?:www\.)?snapchat\.com/add/([a-zA-Z0-9_-]+)},
|
||||
:stackoverflow => %r{\Ahttps?://(?:www\.)?stackoverflow\.com/users/\d+/([a-zA-Z0-9_-]+)},
|
||||
:strava => %r{\Ahttps?://(?:www\.)?strava\.com/athletes/([a-zA-Z0-9_-]+)},
|
||||
:substack => %r{\Ahttps?://(?:www\.)?substack\.com/@([a-zA-Z0-9_-]+)},
|
||||
:telegram => %r{\Ahttps?://(?:www\.)?t\.me/([a-zA-Z0-9_]+)},
|
||||
:threads => %r{\Ahttps?://(?:www\.)?threads\.net/@([a-zA-Z0-9_]+)},
|
||||
:tiktok => %r{\Ahttps?://(?:www\.)?tiktok\.com/@([a-zA-Z0-9_]+)},
|
||||
:twitch => %r{\Ahttps?://(?:www\.)?twitch\.tv/([a-zA-Z0-9_]+)},
|
||||
:twitter_x => %r{\Ahttps?://(?:www\.)?(?:twitter|x)\.com/([a-zA-Z0-9_]+)},
|
||||
:vimeo => %r{\Ahttps?://(?:www\.)?vimeo\.com/([a-zA-Z0-9_]+)},
|
||||
:whatsapp => %r{\Ahttps?://wa\.me/(\d+)},
|
||||
:youtube => %r{\Ahttps?://(?:www\.)?youtube\.com/@([a-zA-Z0-9_-]+)}
|
||||
}.freeze
|
||||
|
||||
NO_USERNAME_PLATFORMS = %w[discord line skype slack].freeze
|
||||
|
||||
def parsed
|
||||
URL_PATTERNS.each do |platform, pattern|
|
||||
names = url.match(pattern)
|
||||
if names
|
||||
return {
|
||||
:platform => platform.to_s,
|
||||
:name => NO_USERNAME_PLATFORMS.include?(platform.to_s) ? platform.to_s.capitalize : names[1]
|
||||
}
|
||||
end
|
||||
end
|
||||
{ :platform => nil, :name => url.gsub(%r{https?://}, "") }
|
||||
end
|
||||
end
|
|
@ -87,6 +87,9 @@ class User < ApplicationRecord
|
|||
|
||||
has_many :reports
|
||||
|
||||
has_many :social_links
|
||||
accepts_nested_attributes_for :social_links, :allow_destroy => true
|
||||
|
||||
scope :visible, -> { where(:status => %w[pending active confirmed]) }
|
||||
scope :active, -> { where(:status => %w[active confirmed]) }
|
||||
scope :identifiable, -> { where(:data_public => true) }
|
||||
|
|
|
@ -9,6 +9,22 @@
|
|||
<%= bootstrap_form_for current_user, :url => { :action => :update }, :html => { :multipart => true, :autocomplete => :off } do |f| %>
|
||||
<%= f.richtext_field :description, :cols => 80, :rows => 20 %>
|
||||
|
||||
<fieldset class="mb-3">
|
||||
|
||||
<%= f.label t(".social_links.title"), :class => "form-label" %>
|
||||
<div id="social_links">
|
||||
<%= f.fields_for :social_links do |social_link_form| %>
|
||||
<div class="social-link-fields row mb-3">
|
||||
<%= social_link_form.text_field :url, :hide_label => true, :wrapper_class => "col-sm-8" %>
|
||||
<%= social_link_form.check_box :_destroy, :wrapper_class => "d-none social_link_destroy" %>
|
||||
<%= social_link_form.label :_destroy, t(".social_links.remove"), :class => "btn btn-outline-primary col-sm-2 align-self-start" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<button id="add-social-link" type="button" class="btn btn-outline-primary"><%= t ".social_links.add" %></button>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="mb-3">
|
||||
<%= f.label t(".image") %>
|
||||
<div class="row">
|
||||
|
|
14
app/views/social_links/_show.html.erb
Normal file
|
@ -0,0 +1,14 @@
|
|||
<ul class="list-unstyled">
|
||||
<% social_links.each do |social_link| %>
|
||||
<li>
|
||||
<%= link_to social_link.url, :class => "icon-link mw-100 text-body-secondary mb-3", :rel => "nofollow me" do %>
|
||||
<%= image_tag "social_link_icons/#{social_link.parsed[:platform].nil? ? 'other' : social_link.parsed[:platform]}.svg",
|
||||
:alt => social_link.parsed[:platform].nil? ? t(".other") : social_link.parsed[:platform],
|
||||
:size => "16" %>
|
||||
<span class="text-truncate">
|
||||
<%= social_link.parsed[:name] %>
|
||||
</span>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
|
@ -231,10 +231,17 @@
|
|||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="richtext text-break clearfix"><%= @user.description.to_html %></div>
|
||||
|
||||
<% if current_user and @user.id == current_user.id %>
|
||||
<div class="my-3">
|
||||
<%= link_to t(".edit_profile"), edit_profile_path, :class => "btn btn-outline-primary" %>
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<%= render "social_links/show",
|
||||
:social_links => @user.social_links %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="col-sm-9">
|
||||
<div class="richtext text-break clearfix"><%= @user.description.to_html %></div>
|
||||
<% if current_user and @user.id == current_user.id %>
|
||||
<div class="my-3">
|
||||
<%= link_to t(".edit_profile"), edit_profile_path, :class => "btn btn-outline-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,6 +14,7 @@ translations:
|
|||
- "*.diary_entries.edit.marker_text"
|
||||
- "*.layouts.project_name.title"
|
||||
- "*.geocoder.search_osm_nominatim.*"
|
||||
- "*.profiles.edit.social_links.remove"
|
||||
- file: "app/assets/javascripts/i18n/embed.js"
|
||||
pretty_print: true
|
||||
only:
|
||||
|
|
|
@ -37,6 +37,10 @@ en:
|
|||
messages:
|
||||
display_name_is_user_n: can't be user_n unless n is your user id
|
||||
models:
|
||||
social_link:
|
||||
attributes:
|
||||
url:
|
||||
http_parse_error: Url should start with http:// or https://
|
||||
user_mute:
|
||||
attributes:
|
||||
subject:
|
||||
|
@ -1963,6 +1967,10 @@ en:
|
|||
show: "Show"
|
||||
delete: "Delete"
|
||||
undelete: "Undo delete"
|
||||
social_links:
|
||||
title: Social Profile Links
|
||||
remove: Remove
|
||||
add: Add Social Link
|
||||
update:
|
||||
success: Profile updated.
|
||||
failure: Couldn't update profile.
|
||||
|
@ -2603,6 +2611,9 @@ en:
|
|||
community group. Anyone can set up or join these. Read more on the %{communities_wiki_link}.
|
||||
communities_wiki: Communities wiki page
|
||||
communities_wiki_url: https://wiki.openstreetmap.org/wiki/User_group
|
||||
social_links:
|
||||
show:
|
||||
other: Other
|
||||
traces:
|
||||
visibility:
|
||||
private: "Private (only shared as anonymous, unordered points)"
|
||||
|
|
10
db/migrate/20250217140049_create_social_links.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
class CreateSocialLinks < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
create_table :social_links do |t|
|
||||
t.references :user, :null => false, :foreign_key => true
|
||||
t.string :url, :null => false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1362,6 +1362,38 @@ CREATE TABLE public.schema_migrations (
|
|||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: social_links; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.social_links (
|
||||
id bigint NOT NULL,
|
||||
user_id bigint NOT NULL,
|
||||
url character varying NOT NULL,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: social_links_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.social_links_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: social_links_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.social_links_id_seq OWNED BY public.social_links.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: user_blocks; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1756,6 +1788,13 @@ ALTER TABLE ONLY public.redactions ALTER COLUMN id SET DEFAULT nextval('public.r
|
|||
ALTER TABLE ONLY public.reports ALTER COLUMN id SET DEFAULT nextval('public.reports_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: social_links id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.social_links ALTER COLUMN id SET DEFAULT nextval('public.social_links_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: user_blocks id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2120,6 +2159,14 @@ ALTER TABLE ONLY public.schema_migrations
|
|||
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);
|
||||
|
||||
|
||||
--
|
||||
-- Name: social_links social_links_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.social_links
|
||||
ADD CONSTRAINT social_links_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: user_blocks user_blocks_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2646,6 +2693,13 @@ CREATE INDEX index_reports_on_issue_id ON public.reports USING btree (issue_id);
|
|||
CREATE INDEX index_reports_on_user_id ON public.reports USING btree (user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_social_links_on_user_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_social_links_on_user_id ON public.social_links USING btree (user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_user_blocks_on_creator_id_and_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -3041,6 +3095,14 @@ ALTER TABLE ONLY public.user_mutes
|
|||
ADD CONSTRAINT fk_rails_591dad3359 FOREIGN KEY (owner_id) REFERENCES public.users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: social_links fk_rails_6034fd4f62; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.social_links
|
||||
ADD CONSTRAINT fk_rails_6034fd4f62 FOREIGN KEY (user_id) REFERENCES public.users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_access_tokens fk_rails_732cb83ab7; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -3446,6 +3508,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('21'),
|
||||
('20250304172798'),
|
||||
('20250304172758'),
|
||||
('20250217140049'),
|
||||
('20250212160355'),
|
||||
('20250206202905'),
|
||||
('20250121191749'),
|
||||
|
|
|
@ -59,5 +59,14 @@ class ProfilesControllerTest < ActionDispatch::IntegrationTest
|
|||
get edit_profile_path
|
||||
assert_select "form > fieldset > div > div.col-sm-10 > div > input[name=avatar_action][checked]", false
|
||||
assert_select "form > fieldset > div > div.col-sm-10 > div > div.form-check > input[name=avatar_action][checked]", false
|
||||
|
||||
# Updating social links should work
|
||||
put profile_path, :params => { :user => { :description => user.description, :social_links_attributes => [{ :url => "https://test.com/test" }] } }
|
||||
assert_redirected_to user_path(user)
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
assert_template :show
|
||||
assert_select ".alert-success", /^Profile updated./
|
||||
assert_select "a", "test.com/test"
|
||||
end
|
||||
end
|
||||
|
|
6
test/factories/social_link.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
FactoryBot.define do
|
||||
factory :social_link do
|
||||
sequence(:url) { |n| "https://test.com/#{n}" }
|
||||
user
|
||||
end
|
||||
end
|
57
test/models/social_link_test.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
require "test_helper"
|
||||
|
||||
class SocialLinkTest < ActiveSupport::TestCase
|
||||
def test_user_required
|
||||
social_link = create(:social_link)
|
||||
|
||||
assert_predicate social_link, :valid?
|
||||
social_link.user = nil
|
||||
assert_not_predicate social_link, :valid?
|
||||
end
|
||||
|
||||
def test_url_required
|
||||
social_link = create(:social_link)
|
||||
|
||||
assert_predicate social_link, :valid?
|
||||
social_link.url = nil
|
||||
assert_not_predicate social_link, :valid?
|
||||
end
|
||||
|
||||
def test_url_https_valid
|
||||
social_link = create(:social_link)
|
||||
|
||||
assert_predicate social_link, :valid?
|
||||
social_link.url = "test"
|
||||
assert_not_predicate social_link, :valid?
|
||||
end
|
||||
|
||||
def test_parsed_platform
|
||||
social_link = create(:social_link, :url => "https://mastodon.social/@test")
|
||||
|
||||
assert_equal "mastodon", social_link.parsed[:platform]
|
||||
assert_equal "test", social_link.parsed[:name]
|
||||
end
|
||||
|
||||
def test_parsed_platform_with_www
|
||||
social_link = create(:social_link, :url => "http://www.mastodon.social/@test")
|
||||
|
||||
assert_equal "mastodon", social_link.parsed[:platform]
|
||||
assert_equal "test", social_link.parsed[:name]
|
||||
end
|
||||
|
||||
def test_parsed_platform_custom_name
|
||||
social_link = create(:social_link, :url => "https://discord.com/users/0")
|
||||
|
||||
assert_equal "discord", social_link.parsed[:platform]
|
||||
assert_equal "Discord", social_link.parsed[:name]
|
||||
end
|
||||
|
||||
def test_parsed_platform_other
|
||||
url = "https://test.com/test"
|
||||
expected = "test.com/test"
|
||||
social_link = create(:social_link, :url => url)
|
||||
|
||||
assert_nil social_link.parsed[:platform]
|
||||
assert_equal social_link.parsed[:name], expected
|
||||
end
|
||||
end
|